Click here to Skip to main content
15,867,453 members
Articles / Programming Languages / Visual Basic
Article

Introduction to TreeView Drag and Drop (VB.NET)

Rate me:
Please Sign up or sign in to vote.
4.88/5 (95 votes)
8 Dec 2004CPOL5 min read 408.2K   5.7K   132   87
Provide drag and drop functionalitly to TreeView controls.

Introduction

TreeView controls are extremely common in applications where it is necessary to present any sort of hierarchy to a user. Usually, the nature of such a hierarchy requires that users have the ability to reorganize it; drag and drop operations providing a natural solution. This article provides an introduction to implementing drag and drop functionality to a TreeView control.

Getting Started

The code in this article assumes you have a form with a TreeView control, this needs to be populated with some TreeNodes (the demo project available at the top of the article provides a method to randomly generate a TreeNode hierarchy). Ensure that the TreeView can accept objects dragged onto it by setting the AllowDrop property to True.

Initiating the Drag

When the user begins the drag action on a TreeNode, the ItemDrag event is fired, we need to handle this:

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

Here we are initiating a drag operation by calling the DoDragDrop method, specifying the TreeNode object being dragged and specifying the Move operation the user will perform if the drag drop is completed. Note that the DragDropEffects enumeration merely describes the cursors (effects) that can be presented during the operation, it will not enforce that the object will ultimately be moved as a result of the successful drag drop operation.

Dragging Over the Control

With the drag operation under way, the TreeView must now react when an object is dragged over it. When this occurs, the DragEnter event is fired that we must handle:

VB
Public Sub TreeView1_DragEnter(ByVal sender As System.Object, _
    ByVal e As System.Windows.Forms.DragEventArgs) _
    Handles TreeView1.DragEnter

    'See if there is a TreeNode being dragged
    If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
        True) Then
        'TreeNode found allow move effect
        e.Effect = DragDropEffects.Move
    Else
        'No TreeNode found, prevent move
        e.Effect = DragDropEffects.None
    End If

End Sub

All we are doing here is checking if there is an object present in the drag drop operation that we are happy to be dropped onto the TreeView, in this case a TreeNode. If a TreeNode is found, then we specify that the Move effect will be displayed on the cursor, otherwise we specify that the None effect will be displayed. Note, you may only select the effect(s) that were specified when the drag drop operation was initiated with the DoDragDrop method (see Initiating the Drag above).

It is important to check that the object of the type you are expecting is present in the drag drop data (in this case, a TreeNode). In this example, we only have one control that is initiating a drag drop operation. However, on a form, there may be many other controls calling the DoDragDrop method; by setting the AllowDrop property to True on a control, you are specifying that it will react whenever any object is dragged over it.

Validating the Drop Target

Above, we looked at ensuring only TreeNodes can be dragged over the TreeView. However, it is also important to ensure that a particular TreeNode within the TreeView is a valid target for the drag drop operation. Therefore, we have to validate the TreeNode as the cursor passes over it by handling the DragOver event:

VB
Public Sub TreeView1_DragOver(ByVal sender As System.Object, _
    ByVale As DragEventArgs) _
    Handles TreeView1.DragOver

    'Check that there is a TreeNode being dragged
    If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
           True) = False Then Exit Sub

    'Get the TreeView raising the event (incase multiple on form)
    Dim selectedTreeview As TreeView = CType(sender, TreeView)

    'As the mouse moves over nodes, provide feedback to
    'the user by highlighting the node that is the
    'current drop target
    Dim pt As Point = _
        CType(sender, TreeView).PointToClient(New Point(e.X, e.Y))
    Dim targetNode As TreeNode = selectedTreeView.GetNodeAt(pt)

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

        '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)

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

        'Currently selected node is a suitable target
        e.Effect = DragDropEffects.Move
    End If

End Sub

Firstly, we are checking that there is a TreeNode object in the drag drop operation. If there is not, we aren't going any further; there is no need to even change the effect because the TreeView would have taken care of that during the DragEnter event handler.

Then next stage is to get the TreeView that fired the event (important if this method is handling multiple TreeView controls on a single form), and work out the TreeNode that is currently under the cursor using the GetNodeAt function. Finally, we must ensure that the TreeNode under the cursor is not the TreeNode that is being dragged or a child of that TreeNode. This is important; if we attempt to drop a TreeNode onto itself or a ChildNode, then the node and its siblings would all just vanish.

Provided the TreeNode under the cursor is a valid drop target, we provide feedback to the user by setting the Move effect.

Performing the Drop

Finally, we need to drop the the TreeNode to complete the operation. This is accomplished by handling the DragDrop event fired by the TreeView:

VB
Public Sub TreeView1_DragDrop(ByVal sender As System.Object, _
    ByVal e As System.Windows.Forms.DragEventArgs) _
    Handles TreeView1.DragDrop

    'Check that there is a TreeNode being dragged
    If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
          True) = False Then Exit Sub

    'Get the TreeView raising the event (incase multiple on form)
    Dim selectedTreeview As TreeView = CType(sender, TreeView)

    'Get the TreeNode being dragged
    Dim dropNode As TreeNode = _
          CType(e.Data.GetData("System.Windows.Forms.TreeNode"), _
          TreeNode)

    'The target node should be selected from the DragOver event
    Dim targetNode As TreeNode = selectedTreeview.SelectedNode

    'Remove the drop node from its current location
    dropNode.Remove()

    'If there is no targetNode add dropNode to the bottom of
    'the TreeView root nodes, otherwise add it to the end of
    'the dropNode child nodes
    If targetNode Is Nothing Then
        selectedTreeview.Nodes.Add(dropNode)
    Else
        targetNode.Nodes.Add(dropNode)
    End If

    'Ensure the newley created node is visible to
    'the user and select it
    dropNode.EnsureVisible()
    selectedTreeview.SelectedNode = dropNode

End Sub

As above, we firstly check that there is a TreeNode present in the drop data and get the TreeView firing the event in case of multiple TreeViews handled by the method. We then locate the node that will be the target of the drop and remove the node that is being moved from its original location.

If there is no target node, we assume the target to be the TreeView itself, and therefore add the node at the end of the TreeView.Nodes collection. Otherwise, we add the node to the end of the target TreeNode.Nodes collection.

Finally, by calling the EnsureVisible method, all ParentNodes of the node we just added will be expanded, making sure that the node is not hidden. Selecting the dropped node will provide feedback to the user by highlighting it once the operation is complete.

Supporting Multiple TreeViews

The code in this article has been designed to allow multiple TreeView controls to support drag and drop operation on the form. To add support for multiple TreeView controls, complete the following:

  1. Add a TreeView control to the form
  2. Set its AllowDrop property to True
  3. Amend each of the methods above to handle the relevant events of the new TreeView, for example:
VB
Public Sub TreeView1_DragDrop(ByVal sender As System.Object, _
    ByVal e As System.Windows.Forms.DragEventArgs) _
    Handles TreeView1.DragDrop, TreeView2.DragDrop

Any number of additional TreeView controls can be added to the form in this way.

Conclusion

I hope this article provides an interesting introduction to Drag and Drop operations. The logic applied in this article can also be applied to other controls allowing a user interface that completely supports Drag and Drop.

Related Articles

If you found this article interesting, you may be interested in other introductory articles relating 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

 
QuestionThanks and small bugfix Pin
LightTempler9-Nov-21 5:47
LightTempler9-Nov-21 5:47 
QuestionCongratulations Pin
PrMarcosF13-Apr-20 14:27
professionalPrMarcosF13-Apr-20 14:27 
QuestionThanks a lot Pin
Member 41476743-Jul-14 3:27
Member 41476743-Jul-14 3:27 
QuestionQuestion on multiple treeviews. Pin
Septimus Hedgehog3-Mar-13 7:46
Septimus Hedgehog3-Mar-13 7:46 
QuestionDrag-Drop in between nodes... Pin
GinoMellino16-Jan-13 14:16
GinoMellino16-Jan-13 14:16 
GeneralMy vote of 5 Pin
1Peltztier20-Jul-12 3:32
1Peltztier20-Jul-12 3:32 
QuestionThank you very much Pin
Douglas074-Apr-12 3:53
Douglas074-Apr-12 3:53 
AnswerRe: Thank you very much Pin
Tom John4-Apr-12 3:58
Tom John4-Apr-12 3:58 
QuestionThank You very Much Pin
MacParekh19-Mar-12 0:06
MacParekh19-Mar-12 0:06 
GeneralMy vote of 5 Pin
Steven St. John21-Jul-11 10:38
Steven St. John21-Jul-11 10:38 
GeneralJust great Pin
Effi b18-Jul-11 7:21
Effi b18-Jul-11 7:21 
GeneralMy vote of 5 Pin
BrianLaF2-Dec-10 4:55
BrianLaF2-Dec-10 4:55 
GeneralMy vote of 5 Pin
Champan1-Jul-10 2:51
Champan1-Jul-10 2:51 
GeneralGood article! Good explanation! Pin
Shane Story14-Jun-10 4:27
Shane Story14-Jun-10 4:27 
GeneralThank you very much Pin
Khalido8r31-Jan-10 18:50
Khalido8r31-Jan-10 18:50 
GeneralThe Bee's Knees Pin
riced28-Oct-08 4:08
riced28-Oct-08 4:08 
GeneralGreat article but wrong category Pin
zuraw27-Aug-08 22:49
zuraw27-Aug-08 22:49 
GeneralRe: Great article but wrong category Pin
Tom John27-Aug-08 23:26
Tom John27-Aug-08 23:26 
GeneralRe: Great article but wrong category Pin
zuraw29-Aug-08 3:16
zuraw29-Aug-08 3:16 
GeneralSlight modification to example code to handle Treeview events automatically. ie scrolling. PinPopular
tony197606194-Mar-08 21:01
tony197606194-Mar-08 21:01 
GeneralRe: Slight modification to example code to handle Treeview events automatically. ie scrolling. Pin
Member 140062618-Feb-19 4:34
Member 140062618-Feb-19 4:34 
GeneralAutoScrolling in TreeView Pin
SkipGalt14-Nov-07 4:47
SkipGalt14-Nov-07 4:47 
GeneralASP.NET 2.0 Pin
nrocha30-Aug-07 23:52
nrocha30-Aug-07 23:52 
GeneralRe: ASP.NET 2.0 Pin
Tom John31-Aug-07 0:10
Tom John31-Aug-07 0:10 
GeneralRe: ASP.NET 2.0 Pin
nrocha31-Aug-07 0:19
nrocha31-Aug-07 0:19 

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.