Browse DevX
Sign up for e-mail newsletters from DevX


Making the Most of the VB TreeView Control : Page 3

Add run-time editing, drag-and-drop features and persistence to the TreeView control.

Implementing Node Drag-and-Drop
The most interesting aspect of the application is the ability to alter the hierarchy itself with drag and drop operations. The TreeView control doesn't support drag and drop operations natively on its own items, so I've chosen to program the OLE drag and drop events. First, you must set the control's OLEDragMode property to Automatic and the OLEDropMode property to Manual. When the user starts dragging a node, the control fires the OLEStartDrag event:

   Private Sub TreeView1_OLEStartDrag( _
      Data As MSComctlLib.DataObject, _
      AllowedEffects As Long)
      If Not Me.TreeView1.SelectedItem Is Nothing Then
           Data.SetData Me.TreeView1.SelectedItem.Key, _
      End If
   End Sub
You set the Data argument of the event handler to the selected node's Key property. You'll see in a moment how the code uses that value. While the user is dragging the node around, VB generates the OLEDragOver event (the sample code ignores this event for controls other than the TreeView control on the form). Listing 1 shows the handler for the OLEDragOver event. As users drag items over existing nodes, they aren't highlighted automatically, so you must highlight each node by setting the TreeView control's DropHighlight property to the appropriate node. To determine the node under the cursor, call the control's HitTest method, and pass the coordinates of the cursor as arguments:

   TreeView1.DropHighlight = TreeView1.HitTest(x, y)
Dragging nodes over nodes currently visible is no problem, but it's harder to drag a node to a node that isn't visible in the TreeView control's window. To do that, you have to force the TreeView control to scroll up or down as the drag operation approaches the top or bottom edge of the control. The TVEdit project uses a Timer that fires every 200 milliseconds to examine the position of the item being dragged every 200 milliseconds. If the item is within 100 pixels from the top or bottom edge of the control, the code scrolls the control. An MSDN Howto article (Q177743) describes this technique in detail. Listing 1 contains a few statements that determine whether to scroll the control's items up or down and enables the Timer control, but the actual scrolling of the control takes place from within the Timer event handler.

When the user drops the item, the control fires the OLEDragDrop event. In this event's handler (see Listing 2) you retrieve the item being dragged and place it under the highlighted node. Because you saved the item's Key to a Data object passed to the event handler as argument, you can quickly retrieve the corresponding node by passing the key as argument to the Nodes collection. To move the original node under a new parent node, we simply set its ParentNode property to the selected node. By changing the node's parent, in effect, we move it under a new parent. Changing the node's parent also moves all subordinate nodes . The code also makes sure that the item can be dropped onto the selected node. For example, an item can't be dropped on one of its child nodes, for example, because this would create a circular reference.

The code presented so far takes care of the run-time editing operations on the TreeView control. Examine the control's KeyDown event handler to see how the control handles the other keystrokes. It's very easy to manipulate the nodes of the control (add new nodes, delete existing ones and edit any node's caption) with the keyboard. To change the hierarchy of a node, drag it with the mouse and drop it on its new parent node.

Thanks for your registration, follow us on our social networks to keep up-to-date