Click here to Skip to main content
15,878,809 members
Articles / Desktop Programming / Windows Forms

Drag and Drop Persisting TreeView Control (VB.NET)

Rate me:
Please Sign up or sign in to vote.
4.55/5 (23 votes)
29 Nov 2012CPOL4 min read 150.3K   2.9K   67   24
Extending the TreeView control to support drag and drop and persistance.

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:

VB
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:

VB
Public Sub TreeView1_ItemDrag(ByVal sender As System.Object, _
    ByVal e As System.Windows.Forms.ItemDragEventArgs) _
    Handles TreeView1.ItemDrag
        
    'Set the drag node and initiate the DragDrop 
    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:

VB
Protected Overrides Sub OnItemDrag( _
    ByVal e As System.Windows.Forms.ItemDragEventArgs)
    
    'Ensure the base method is called 
    MyBase.OnItemDrag(e)
    
    'Set the drag node and initiate the DragDrop 
    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:

VB
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:

VB
Public Sub SaveToXml(ByVal path As String)
        
    'Create as serializer and file to save TreeViewData
    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)
    
    'Generate TreeViewData from TreeView and serialize the file
    ser.Serialize(writer, New TreeViewData(Me))
    
    'Tidy up
    writer.Close()
    file.Close()
    file = Nothing

End Sub
    
    
Public Sub LoadFromXml(ByVal path As String)
    
    'Create as serializer and get the file to deserialize
    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)

    'Deserialize the file and populate the treeview
    Dim treeData As TreeViewData = _
        CType(ser.Deserialize(reader), TreeViewData)
    treeData.PopulateTree(Me)

    'Tidy up
    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:

VB
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:

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) RedFrog.com Limited
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Member 158913017-Mar-21 11:05
Member 158913017-Mar-21 11:05 
QuestionWrite to Excel? Pin
dutsnekcirf25-Oct-08 8:22
dutsnekcirf25-Oct-08 8:22 
GeneralThis is exactly what I need, but just a little bit more help. Pin
dutsnekcirf24-Oct-08 12:38
dutsnekcirf24-Oct-08 12:38 
GeneralRe: This is exactly what I need, but just a little bit more help. Pin
dutsnekcirf24-Oct-08 12:42
dutsnekcirf24-Oct-08 12:42 
Generalgreate stuff and bug fixing Pin
carvals22-Jun-08 9:43
carvals22-Jun-08 9:43 
GeneralRe: greate stuff and bug fixing Pin
Tom John22-Jun-08 23:51
Tom John22-Jun-08 23:51 
GeneralVB.NET Treeview Parent/Child MS Access Pin
csebelle22-May-07 17:57
csebelle22-May-07 17:57 
Generalrecycle bin Pin
syriast30-Jul-06 3:37
syriast30-Jul-06 3:37 
GeneralRe: recycle bin Pin
Tom John30-Jul-06 8:17
Tom John30-Jul-06 8:17 
GeneralFormatting Treeview Text Pin
seanhepburn200212-Mar-06 2:53
seanhepburn200212-Mar-06 2:53 
GeneralVery Good Pin
luforever9-Feb-06 11:08
luforever9-Feb-06 11:08 
GeneralRe: Very Good Pin
Tom John9-Feb-06 11:11
Tom John9-Feb-06 11:11 
GeneralResolve the bugs and suggest Pin
Mahmmoud Mahdi9-Jan-06 11:02
Mahmmoud Mahdi9-Jan-06 11:02 
thanks Tom for ur great work, the bugs in this version was when the node drag into one of it's child
my change to solve this in your DragOver function:

'See if the targetNode is currently selected, if so no need to validate again
'If Not (SelectedNode Is targetNode) Then
'replaced with
If Not (Me Is targetNode) Then
'Select the node currently under the cursor
SelectedNode = targetNode
.....

and as when the node might be droped into the same parent; no need here to do any thing and to provide a feedback to the user with that, i include the following code in the OnDragOver function:

OMG | :OMG:
'Check that the selected node is not the dropNode and also that it
'is not a child of the dropNode and therefore an invalid target
Dim dropNode As TreeNode = CType(e.Data.GetData("System.Windows.Forms.TreeNode"), TreeNode)

'------My Code ----->
If (dropNode.Parent Is targetNode) Then
e.Effect = DragDropEffects.None
Exit Sub
End If
'------End modify here-----<

Do Until targetNode Is Nothing
If targetNode Is dropNode Then
e.Effect = DragDropEffects.None
Exit Sub
End If
targetNode = targetNode.Parent
Loop

Laugh | :laugh:
anyway, thanks to Tom John's for his great work

Al-QurSaan
GeneralProblem when dropping an item on itself Pin
Richard Heinrich23-Nov-05 0:29
Richard Heinrich23-Nov-05 0:29 
GeneralPrevious version Pin
Arkett6-Nov-05 4:49
Arkett6-Nov-05 4:49 
GeneralXML Serialization CDATA element Pin
spratticus31-Mar-05 9:55
spratticus31-Mar-05 9:55 
GeneralAwesome! Pin
Todd Davis27-Feb-05 7:41
Todd Davis27-Feb-05 7:41 
GeneralRe: Awesome! Pin
Tom John27-Feb-05 9:01
Tom John27-Feb-05 9:01 
GeneralLabel edit and sort Pin
codegalaxy24-Feb-05 2:46
codegalaxy24-Feb-05 2:46 
GeneralRe: Label edit and sort Pin
Tom John2-Mar-05 5:07
Tom John2-Mar-05 5:07 
GeneralASP.NET Pin
dandrade5-Feb-05 8:12
dandrade5-Feb-05 8:12 
GeneralRe: ASP.NET Pin
Tom John11-Feb-05 10:01
Tom John11-Feb-05 10:01 
Generalwqeqwe Pin
Anonymous3-Feb-05 15:07
Anonymous3-Feb-05 15:07 
GeneralRe: wqeqwe Pin
Anonymous3-Feb-05 15:08
Anonymous3-Feb-05 15:08 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.