|
|
Title | Add nodes to a TreeView control at run time, and let the user drag and drop TreeView nodes |
Description | |
Keywords | TreeView, AddNode, drag and drop |
Categories | Controls |
|
|
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
|
|
|
|
|
|