Home
Search
 
What's New
Index
Books
Links
Q & A
Newsletter
Banners
 
Feedback
Tip Jar
 
C# Helper...
 
XML RSS Feed
Follow VBHelper on Twitter
 
 
 
MSDN Visual Basic Community
 
 
 
 
 
TitleAdd nodes to a TreeView control at run time, and let the user drag and drop TreeView nodes
Description
KeywordsTreeView, AddNode, drag and drop
CategoriesControls
 
Use the TreeView's Node collection's Add method to create new nodes. When the program loads, it creates several TreeView nodes. If begins by adding images from the TreeImage control array of Image controls to the ImageList control named TreeImages. The TreeView displays the images in this ImageList. (Note that it is often easier to build this ImageList at runtime rather than at design time. Working with ImageLists at design time can be a hassle.)

The program starts the nodes' keys with the letters f for factory, g for group, and p for person. This makes it easier to figure out what kind of node each is later.

 
Private Sub Form_Load()
Dim i As Integer
Dim factory As Node
Dim group As Node
Dim person As Node

    ' Load pictures into the ImageList.
    For i = 1 To 6
        TreeImages.ListImages.Add , , TreeImage(i).Picture
    Next i
    
    ' Attach the TreeView to the ImageList.
    OrgTree.ImageList = TreeImages
    
    ' Create some nodes.
    Set factory = OrgTree.Nodes.Add(, , "f R & D", "R & D", _
        otFactory, otFactory2)
    Set group = OrgTree.Nodes.Add(factory, tvwChild, "g " & _
        "Engineering", "Engineering", otGroup, otGroup2)
    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        "Cameron, Charlie", "Cameron, Charlie", otPerson, _
        otPerson2)
    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        "Davos, Debbie", "Davos, Debbie", otPerson, _
        otPerson2)
    person.EnsureVisible
    Set group = OrgTree.Nodes.Add(factory, tvwChild, "g " & _
        "Test", "Test", otGroup, otGroup2)
    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        "Able, Andy", "Andy, Able", otPerson, otPerson2)
    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        "Baker, Betty", "Baker, Betty", otPerson, otPerson2)
    person.EnsureVisible
    
    Set factory = OrgTree.Nodes.Add(, , "f Sales & " & _
        "Support", "Sales & Support", otFactory, otFactory2)
    Set group = OrgTree.Nodes.Add(factory, tvwChild, "g " & _
        "Showroom Sales", "Showroom Sales", otGroup, _
        otGroup2)
    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        "Gaines, Gina", "Gaines, Gina", otPerson, otPerson2)
    person.EnsureVisible
    Set group = OrgTree.Nodes.Add(factory, tvwChild, "g " & _
        "Field Service", "Field Service", otGroup, otGroup2)
    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        "Helms, Harry", "Helms, Harry", otPerson, otPerson2)
    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        "Ives, Irma", "Ives, Irma", otPerson, otPerson2)
    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        "Jackson, Josh", "Jackson, Josh", otPerson, _
        otPerson2)
    person.EnsureVisible
    Set group = OrgTree.Nodes.Add(factory, tvwChild, "g " & _
        "Customer Support", "Customer Support", otGroup, _
        otGroup2)
    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        "Klug, Karl", "Klug, Karl", otPerson, otPerson2)
    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        "Landau, Linda", "Landau, Linda", otPerson, _
        otPerson2)
    person.EnsureVisible
End Sub
 
Function NodeType returns an ObjectTytpe indicating the type of a TreeView node. It figures this out by examining the first letter in the node's Key.
 
Private Function NodeType(test_node As Node) As ObjectType
    If test_node Is Nothing Then
        NodeType = otNone
    Else
        Select Case Left$(test_node.Key, 1)
            Case "f"
                NodeType = otFactory
            Case "g"
                NodeType = otGroup
            Case "p"
                NodeType = otPerson
        End Select
    End If
End Function
 
When the user selects the Add Factory menu item, the program prompts the user for the name of the new factory. It then creates a new factory node at the TreeView root.
 
' Add a new factory.
Private Sub mnuAddFactory_Click()
Dim name As String
Dim factory As Node

    name = InputBox("Factory Name", "New Factory", "")
    If name = "" Then Exit Sub
    
    Set factory = OrgTree.Nodes.Add(, , "f " & name, name, _
        otFactory, otFactory2)
    factory.EnsureVisible
End Sub
 
When the user selects the Add Group menu item, the program prompts the user for the new group's name. It finds the currently selected TreeView node and determines the node's type. If the node is not a factory, the program moves up the tree to find the node's factory. It then adds the new group node.
 
' Add a new group.
Private Sub mnuAddGroup_Click()
Dim name As String
Dim factory As Node
Dim group As Node

    name = InputBox("Group Name", "New Group", "")
    If name = "" Then Exit Sub
    
    ' Find the factory that should hold the new group.
    Set factory = OrgTree.SelectedItem
    If NodeType(factory) = otPerson Then _
        Set factory = factory.Parent
    If NodeType(factory) = otGroup Then _
        Set factory = factory.Parent

    Set group = OrgTree.Nodes.Add(factory, tvwChild, "g " & _
        name, name, otGroup, otGroup2)
    group.EnsureVisible
End Sub
 
When the user selects the Add Person menu item, the program prompts the user for the new person's name. It finds the currently selected TreeView node and determines the node's type. If the node is a person, the program moves up the tree to find the person's group. It then adds the new group node. Note that the selected node cannot be a factory because the program disables the Add Person menu item when a factory is selected.
 
' Add a new person.
Private Sub mnuAddPerson_Click()
Dim name As String
Dim group As Node
Dim person As Node

    name = InputBox("Person Name", "New Person", "")
    If name = "" Then Exit Sub
    
    ' Find the group that should hold the new person.
    Set group = OrgTree.SelectedItem
    If NodeType(group) = otPerson Then _
        Set group = group.Parent

    Set person = OrgTree.Nodes.Add(group, tvwChild, "p " & _
        name, name, otPerson, otPerson2)
    person.EnsureVisible
End Sub
 
When the user opens the main menu Nodes, the mnuNodes_Click event handler determines the kind of node selected and enables and disables the appropriate menu items.
 
Private Sub mnuNodes_Click()
Dim selected_node As Node
Dim selected_type As ObjectType

    Set selected_node = OrgTree.SelectedItem
    If selected_node Is Nothing Then
        selected_type = otNone
    Else
        selected_type = NodeType(selected_node)
    End If

    ' You can always add a factory.
    
    ' You can add a group if a factory, person, or
    ' group is selected.
    mnuAddGroup.Enabled = (selected_type <> otNone)
    
    ' You can add a person if a group or person
    ' is selected.
    mnuAddPerson.Enabled = (selected_type = otPerson) _
        Or (selected_type = otGroup)
End Sub
 
The last piece of the program lets you drag and drop nodes from one part of the tree to another. When the user presses the mouse down over a node, the OrgTree_MouseDown event handler saves the node under the mouse.

When the user moves the mouse, the OrgTree_MouseMove event handler begins a drag by calling the TreeView control's Drag method.

As the user drags the mouse over the TreeView control, its OrgTree_DragOver event handler fires. This routine finds the node under the mouse. If the target node is appropriate (e.g. the dragging node is a person and the target node is a group), the routine sets the TreeView control's DropHighlight property to point to the target node. This highlights the target. If the drop is inappropriate (e.g. dragging a factory onto a group), the code sets the DropHighlight property to Nothing so no node is highlighted.

SFinally, when the user releases the node, the OrgTree_DragDrop event handler checks whether the TreeView's DropHighlight property is Nothing. If DropHighlight is not nothing, then the drop is appropriate so the code makes the source node a child of the target node.

 
Private SourceNode As Object
Private SourceType As ObjectType
Private TargetNode As Object

' Save the node pressed so we can drag it later.
Private Sub OrgTree_MouseDown(Button As Integer, Shift As _
    Integer, x As Single, y As Single)
    Set SourceNode = OrgTree.HitTest(x, y)
End Sub

' Start a drag if one is not in progress.
Private Sub OrgTree_MouseMove(Button As Integer, Shift As _
    Integer, x As Single, y As Single)
    If Button = vbLeftButton Then
        ' Start a new drag. Note that we do not get
        ' other MouseMove events while the drag is
        ' in progress.
        
        ' See what node we are dragging.
        SourceType = NodeType(SourceNode)

        ' Select this node. When no node is highlighted,
        ' this node will be displayed as selected. That
        ' shows where it will land if dropped.
        Set OrgTree.SelectedItem = SourceNode

        ' Set the drag icon for this source.
        OrgTree.DragIcon = IconImage(SourceType)
        OrgTree.Drag vbBeginDrag
    End If
End Sub

' The mouse is being dragged over the control.
' Highlight the appropriate node.
Private Sub OrgTree_DragOver(Source As Control, x As _
    Single, y As Single, State As Integer)
Dim target As Node
Dim highlight As Boolean

    ' See what node we're above.
    Set target = OrgTree.HitTest(x, y)
    
    ' If it's the same as last time, do nothing.
    If target Is TargetNode Then Exit Sub
    Set TargetNode = target
    
    highlight = False
    If Not (TargetNode Is Nothing) Then
        ' See what kind of node were above.
        If NodeType(TargetNode) + 1 = SourceType Then _
            highlight = True
    End If
    
    If highlight Then
        Set OrgTree.DropHighlight = TargetNode
    Else
        Set OrgTree.DropHighlight = Nothing
    End If
End Sub

' The user is dropping. See if the drop is valid.
Private Sub OrgTree_DragDrop(Source As Control, x As _
    Single, y As Single)
    If Not (OrgTree.DropHighlight Is Nothing) Then
        ' It's a valid drop. Set source node's
        ' parent to be the target node.
        Set SourceNode.Parent = OrgTree.DropHighlight
        Set OrgTree.DropHighlight = Nothing
    End If

    Set SourceNode = Nothing
    SourceType = otNone
End Sub
 
 
Copyright © 1997-2010 Rocky Mountain Computer Consulting, Inc.   All rights reserved.
  Updated