Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

ListBox to TreeView Drag and Drop

0.00/5 (No votes)
23 May 2006 1  
In this article, we will learn how to drag an item from a ListBox and drop the dragged item to a TreeView. We will also discuss how to create a folder in a TreeView and delete the folder.

Introduction

In this article, we will learn how to drag an item from a ListBox and drop the dragged item to a TreeView. We will also discuss how to create a folder in a TreeView and delete the folder.

The Module Idea

The module populates the ListBox with �ContactName� values from the Customers table in the NorthWind database of SQL Server 2000. In the TreeView, there is a root folder named �Country�. By clicking on the �NewFolder� button, the user can create a new folder under the Country folder and can name it with the proper country name. When the program runs, you will see the following screen:

Fig. (a) Initial drag-drop screen

After the drag and drop activity, you will have something like what is shown in the following screenshot:

Fig. (b) Final drag-drop screen

Customers enlisted in the adjoining ListBox can be dragged and dropped under the user created folders. Customers can only be dropped under folders. However, customers listed in the TreeView can be dragged and dropped within the TreeView. To distinguish between the customers who are in the TreeView and who are not in the TreeView, the module changes the color of customers in the ListBox from blue to black, the moment a customer get dragged and dropped in to the TreeView. The user can delete a folder by clicking on the �DeleteFolder� button. Doing so will change the color of those items in the ListBox which were under this deleted folder.

In this module, the names of the different controls are:

  • lstCust: ListBox
  • trvCntry: TreeView

Drag-Drop Operation

In the drag operation of an item from the ListBox, the following events participate:

ListBox_MouseDown

This event occurs when the mouse pointer is over the control and a mouse button is pressed. We use this event to capture the item which is being dragged from the ListBox. The following line of code accomplishes this:

lstCust.Items(lstCust.IndexFromPoint(e.X, e.Y)).ToString()

where X gets the x-coordinate of the mouse click and Y gets the y-coordinate of the mouse click. IndexFromPoint returns the zero-based index of the item at the specified coordinates.

DoDragDrop Method: Begins a drag-and-drop operation.
Public Function DoDragDrop( _
   ByVal data As Object, _
   ByVal allowedEffects As DragDropEffects _
) As DragDropEffects

Parameters

  • data - The data to drag.
  • allowedEffects - One of the DragDropEffects values.

    The allowedEffects parameter determines which drag operations can occur.

In our module, we have used the following line of code:

DoDragDrop(strItem, DragDropEffects.All)

DragDropEffects specifies the effects of a drag-and-drop operation. The members of DragDropEffects are enlisted below:

  • All - The data is copied, removed from the drag source, and scrolled in the drop target.
  • Copy - The data is copied to the drop target.
  • Link - The data from the drag source is linked to the drop target.
  • Move - The data from the drag source is moved to the drop target.
  • None - The drop target does not accept the data.
  • Scroll - Scrolling is about to start or is currently occurring in the drop target.

In the drop operation of the item from the ListBox, on the TreeView, the following events participate:

trvCntry_DragEnter

This event occurs when an object is dragged into the control's bounds. We have written the following lines of code in this event:

If e.Data.GetDataPresent(DataFormats.Text) Then
    e.Effect = DragDropEffects.Move
Else
    e.Effect = DragDropEffects.None
End If
  • e.Data gets the IDataObject (provides a format-independent mechanism for transferring data) that contains the data associated with this event.
  • e.Data.GetDataPresent: we can use the GetDataPresent method to determine whether the data matches the format requirements of the control onto which the data is being dragged.
  • e.Effect gets or sets which drag-and-drop operations are allowed by the target of the drag event.

trvCntry_DragDrop

This event occurs when a drag-and-drop operation is completed. We have written the following lines of code in this event. We store the dragged item in a dummy node to be dropped on the TreeView:

strNodeDragged = CType(e.Data.GetData(strDummy.GetType), String)
DragNode = New TreeNode(strNodeDragged)

Next, we find the target item in the TreeView on which the item is to be dropped:

position.X = e.X
position.Y = e.Y

PointToClient computes the location of the specified screen point into the client coordinates:

position = trvCntry.PointToClient(position)
DropNode = Me.trvCntry.GetNodeAt(position)

We validate the target TreeNode as follows. It should be a RootNode:

If IsNothing(DropNode) Or DropNode.Text = "Country" Then
    Exit Sub
End If

To ensure that items should only be dragged on folders, we assign �N� to the items and �Y� to the folder node, by editing the Tag property of TreeNode as shown below:

If IsNothing(DragNode.Tag) Then
    DragNode.Tag = "N"
End If

Now, our next task is to check whether the dragged item is already in the TreeView or not. We do this by calling the ExistInTreeView () method as shown below:

'*************************************************************

    ' Function Name :   ExistInTreeView

    ' Purpose       :   This Function Removes The DragNode

    '                   from the tree from its Previous Place

    ' Input         :   DragNode,Node

    ' Output        :   Integer

    ' Author        :   Ujwal Watgule

    ' Date          :   6th May  2006

    ' Modification History

    ' --------------------------------------------------------

'*************************************************************

Private Function ExistInTreeView(ByVal node As TreeNode, _
        ByVal nddrag As TreeNode) As Integer
    Dim anode As TreeNode
    Try
        anode = New TreeNode()
        For Each anode In node.Nodes
            If Trim(anode.Text) = Trim(nddrag.Text) Then
                trvCntry.Nodes.Remove(anode)
                Return sThree

            End If
            If anode.Nodes.Count > 0 Then
                ExistInTreeView(anode, nddrag)
            End If
            If Trim(anode.Text) = Trim(nddrag.Text) Then
                trvCntry.Nodes.Remove(anode)
                Return sThree

            End If
        Next
    Catch ex As Exception
        Throw ex
    End Try
End Function

As shown below, we loop through every node of the TreeView and make sure that the node which is being dragged gets removed from its previous parent folder.

mTrNode = New TreeNode()
For Each mTrNode In trvCntry.Nodes
    ExistInTreeView(mTrNode, DragNode)
Next

Now, we are ready to attach the dragged item to the targeted node of the TreeView.

If the targeted node is a folder node, then the dragged item can be inserted with the help of the following line of code. But if the targeted node is not a folder node, then the dragged item must be inserted in the parent of the targeted node. As shown in the following lines of code, we have set the Tag property of the dragged item to �N� whose significance we have already explained.

If DropNode.Tag = "Y" Then
    DropNode.Nodes.Insert(DropNode.Index + 1, DragNode)
    DragNode.Tag = "N"
    DragNode.ImageIndex = 5
    DragNode.SelectedImageIndex = 5
    DropNode.Expand()
Else
    DropNode.Parent.Nodes.Insert(DropNode.Index + 1, DragNode)
    DragNode.Tag = "N"
    DragNode.ImageIndex = 5
    DragNode.SelectedImageIndex = 5
    DropNode.Expand()
End If

We have also set the ImageIndex and SelectedImageIndex properties of the node to �5� so that the folder icon should not appear in front of them either in selected mode or unselected mode.

Now, the item is successfully dropped under the targeted folder. The remaining task is to reflect the correct item path in the adjoining ListBox. We use the UpdateListItem method to attach the folder path to the corresponding item present in the ListBox for which the folder acts as a parent.

New Folder Button

We can add new node under the Country folder with the help of a New Folder button. We have written the following lines of code in the New Folder button Click event. To ensure that the folder is created under the folder node only, we check the Tag property of the node selected. If it is �Y�, then that node is eligible to act as a parent for the other node.

'Make sure the folder is being created under folder node only

If trvCntry.SelectedNode.Tag = "Y" Then
    SubFolder = New TreeNode()
'If node selected is the last node 

If IsNothing(trvCntry.SelectedNode.LastNode) Then
    trvCntry.SelectedNode.Nodes.Insert(
         trvCntry.SelectedNode.Index + 1, SubFolder)
    trvCntry.SelectedNode.Expand()
Else
    trvCntry.SelectedNode.Nodes.Insert(
         trvCntry.SelectedNode.LastNode.Index + 1, SubFolder)
    trvCntry.SelectedNode.Expand()
End If
SubFolder.Tag = "Y"
SubFolder.ImageIndex = 0
SubFolder.Text = "NewFolder"
trvCntry.SelectedNode = SubFolder
trvCntry.LabelEdit = True
trvCntry.SelectedNode.BeginEdit()
SubFolder.NodeFont = mFnt
End If

Delete Folder Button

The Delete Folder button allows us to delete a folder, and thereby any other items present under that folder to get refreshed (i.e., their color changes from black to blue) in the ListBox. As shown in the following code snippet, a user is not allowed to delete the �Country� folder.

If trvCntry.SelectedNode.Text = "Country" Then
    Exit Sub
End If
If trvCntry.SelectedNode.Tag = "Y" Then
    DeleteItems(trvCntry.SelectedNode)
    trvCntry.SelectedNode.Remove()
End If

Now, to refresh the items under the folder to be deleted, we call the method DeleteItems():

'*****************************************************

    ' Function Name :   DeleteItems

    ' Purpose       :   This Subroutine Deletes

    '                   The item From the Treeview

    ' Input         :   Treenode

    ' Output        :   Nothing

    ' Author        :   Ujwal Watgule

    ' Date          :   11th May  2006

'*****************************************************

Private Sub DeleteItems(ByVal mNode As TreeNode)
    Dim aNode As TreeNode
    Try
        For Each aNode In mNode.Nodes
            DeleteItems(aNode)
            RefreshList(aNode.Text)
        Next
    Catch ex As Exception
        Throw ex
    End Try
End Sub

The DeleteItems() method, in turn, calls the RefreshList method as shown below:

'*********************************************************

' Function Name :   RefreshList

' Purpose       :   This Subroutine Refreshes The Listbox 

' Input         :   Items Name

' Output        :   Nothing

' Author        :   Ujwal Watgule

' Date          :   11th May 2006

'*********************************************************

Private Sub RefreshList(ByVal mItem As String)
    Dim strRefreshListItem As String
    Dim strChkItem As String
    Dim intCntr, icntr As Integer
    Try
        For intCntr = 0 To lstCust.Items.Count - 1
            strRefreshListItem = lstCust.Items(intCntr)
            For icntr = 0 To strRefreshListItem.Length - 1
                If mItem = strRefreshListItem.Substring(0, icntr) Then
                    strChkItem = mItem
                    lstCust.Items.RemoveAt(intCntr)
                    lstCust.Items.Insert(intCntr, (strChkItem))
                    lstCust.Refresh()
                    Exit For
                End If
            Next
        Next
    Catch ex As Exception
        Throw ex
    End Try
End Sub

Conclusion

In this article, we have learned about the events of ListBox and TreeView which participate in a drag and drop operation. We have also seen how to create a new folder in a TreeView and the procedure for deleting a folder. In my next article, we shall learn how to save the tree hierarchy in a database and populate the same at runtime. Till then, have a nice time.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here