Introduction
In the previous articles Introduction to TreeView Drag and Drop and Using Serialization to Persist TreeView Control, we looked at persisting and implementing drag and drop functionality to an instance of the TreeView
control. In this article, we will take this a step further by extending the TreeView
control to incorporate this functionality, making it available for reuse within your projects.
This article will not cover the topics outlined in the previous articles, it will merely highlight the changes required to implement the functionality into an extended TreeView
class. It is therefore recommended that you familiarize yourself with these articles if you want to have
a full understanding of the project.
Getting Started
Firstly, we are creating an extended user control that's inherited from the standard TreeView
control:
Public Class DragDropPersistingTreeView
Inherits System.Windows.Forms.TreeView
...
End Class
Usually when creating a custom user control, we include the line Inherits
System.Windows.Forms.UserControl
, which provides us with a blank control to work with. Here we are replacing this line with Inherits
System.Windows.Forma.TreeView
, which allows our new control to automatically include all the functionality of the TreeView
control without the need for any additional coding.
Overriding Drag and Drop Methods
In the article Introduction to TreeView Drag and Drop, we had to handle the events fired by the TreeView
control that was related to drag and drop activities from within the parent form:
Public Sub TreeView1_ItemDrag(ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.ItemDragEventArgs) _
Handles TreeView1.ItemDrag
DoDragDrop(e.Item, DragDropEffects.Move)
End Sub
Now that we are extending the TreeView
control, we need to handle the drag and drop events within the class, therefore the above method needs to be replaced with:
Protected Overrides Sub OnItemDrag( _
ByVal e As System.Windows.Forms.ItemDragEventArgs)
MyBase.OnItemDrag(e)
DoDragDrop(e.Item, DragDropEffects.Move)
End Sub
While overriding methods in the inherited classes, it is important to ensure that the overridden method in the base class is called with the relevant parameters. This is to ensure that any delegate watching for the event outside of the class will still receive the event, so we include the line:
MyBase.OnItemDrag(e)
Notice this method is declared as Protected
, this means that it is only available to classes that are derived from this class. Therefore you would be unable to access the OnItemDrag
method of a TreeView
from the form or control you place the control on.
The methods OnDragEnter
, OnDragOver
, OnDragDrop
, and OnDragLeave
have also been overridden in this way; full documentation is included in the attached project source code at the top of the page. With these methods overridden, you have extended the standard TreeView
control to support basic drag and drop operations.
For additional information related to overriding methods, MSDN is a good starting point.
Persisting TreeView Data
In the article Using Serialization to Persist TreeView Control, we created two serializable structures to represent the TreeView
and its TreeNode
collection, these structures have been lifted directly from this article and placed within the extended TreeView
class. However the methods used to expose the load and save functionality need to be modified slightly:
Public Sub SaveToXml(ByVal path As String)
Dim ser As New _
System.Xml.Serialization.XmlSerializer(GetType(TreeViewData))
Dim file As New System.IO.FileStream(path, IO.FileMode.Create)
Dim writer As New System.Xml.XmlTextWriter(file, Nothing)
ser.Serialize(writer, New TreeViewData(Me))
writer.Close()
file.Close()
file = Nothing
End Sub
Public Sub LoadFromXml(ByVal path As String)
Dim ser As New _
System.Xml.Serialization.XmlSerializer(GetType(TreeViewData))
Dim file As New System.IO.FileStream(path, IO.FileMode.Open)
Dim reader As New System.Xml.XmlTextReader(file)
Dim treeData As TreeViewData = _
CType(ser.Deserialize(reader), TreeViewData)
treeData.PopulateTree(Me)
reader.Close()
file.Close()
file = Nothing
End Sub
Again, we are creating an XmlSerializer
to do the hard work of storing and retrieving the TreeView
data. However rather than persisting the data from a TreeView
object passed to the methods as a parameter (as in the original article), here we are persisting the extended TreeView
itself by passing it as a parameter in the TreeViewData
constructor and PopulateTree
method.
Using the Control
The downloads at the top of this page provide a sample project with the DragDropPersistingTreeView
control in action as well as
a single class file for the control. You can build this class into your own project or use it in the same way as any other user control by dragging it from the toolbox to your form or control designer.
Drag and drop functionality will work straight away, provided you set the AllowDrop
property to True
. To load and save the contents of the TreeView
, add a couple of buttons to your form and handle their Click
events:
Private Sub SaveButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles SaveButton.Click
DragDropPersistingTreeView1.SaveToXml( _
"C:\Temp\DragDropPersistingTreeView1.xml")
End Sub
Private Sub LoadButton_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles LoadButton.Click
DragDropPersistingTreeView1.LoadFromXml( _
"C:\Temp\DragDropPersistingTreeView1.xml")
End Sub
Conclusion
I hope this article provides an interesting introduction to extending controls, particularly the TreeView
, by building on the functionality developed in previous articles into a single control.
Related Articles
If you found this article interesting, you may be interested in other introductory articles related to the TreeView
control: