Click here to Skip to main content
Click here to Skip to main content

ListBox to TreeView Drag and Drop

By , 23 May 2006
 

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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ujwal Watgule
Software Developer
India India
Member
Hello Reader, This is Ujwal N.W. Senior Software Developer working with a large MNC. I develop applications in Microsoft .NET Technologies.
Get me at http://thinketh-ujwal.blogspot.com/

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionCan you post a sample code using Drag and Drop with Listview to Listview control in ASP.NET web form?memberThere is always the way to do it, but I don't know20 Nov '08 - 7:01 
Excelent code, but can you do the same thing in ASP.net web form too?
Please post code too.
QuestionDragnDrop subitems in ListviewmemberMember 468407721 Jul '08 - 14:20 
Hi Im trying to drag and drop from one listview to another listview
 
the problem im having is that although i can drag and drop the first column items I cant get the subitems to move to the other listview.
I was hoping someone could help me out.
 

Private Sub ListView_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListView1.DragEnter, ListView2.DragEnter, FileListBox1.DragEnter
' Check for the custom DataFormat ListViewItem array.
If e.Data.GetDataPresent("System.Windows.Forms.ListViewItem()") Then
e.Effect = DragDropEffects.Move
Else
e.Effect = DragDropEffects.None
End If
End Sub
Private Sub ListView_ItemDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.ItemDragEventArgs) Handles ListView1.ItemDrag, ListView2.ItemDrag
Dim myItem As ListViewItem
Dim myItems(sender.SelectedItems.Count - 1) As ListViewItem
Dim i As Integer = 0
 
' Loop though the SelectedItems collection for the source.
For Each myItem In sender.SelectedItems
' Add the ListViewItem to the array of ListViewItems.
myItems(i) = myItem
i = i + 1
Next
' Create a DataObject containg the array of ListViewItems.
sender.DoDragDrop(New DataObject("System.Windows.Forms.ListViewItem()", myItems), DragDropEffects.All)
End Sub
 
Private Sub ListView_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListView1.DragDrop, ListView2.DragDrop, FileListBox1.DragDrop
Dim myItem As ListViewItem
Dim myItems() As ListViewItem = e.Data.GetData("System.Windows.Forms.ListViewItem()")
Dim i As Integer = 0
 
For Each myItem In myItems
' Add the item to the target list.
sender.Items.Add(myItems(i).Text)
' Remove the item from the source list.
If sender Is ListView2 Then
ListView1.Items.Remove(ListView1.SelectedItems.Item(0))
Else
ListView2.Items.Remove(ListView2.SelectedItems.Item(0))
End If
i = i + 1
Next
End Sub

GeneralExcilent work [modified]memberThorgalRose28 Jan '07 - 21:51 
Congratulations, it is an excilent work, thanks very much
 

-- modified at 3:56 Monday 29th January, 2007
 
Can you telle me where i can find those images, which are in the imagelist
 
Tx
GeneralDnD for multiple ListViewItem'smembermk-orange26 Sep '06 - 6:46 
Hi Ujwal!
 
Your code is very nice!
I’m beginner .NET programmer and I need some help.
I want to do Drag and Drop operation for multiple ListViewItem’s from ListView control to TreeView control at once. And I try to pass in DoDragDrop() method ListView.CheckedItems (or ListView.SelectedItems) collection but it doesn’t work.
 
I hope for your explanation.
 
Thanks,
Mike.
GeneralRe: DnD for multiple ListViewItem'smemberUjwal Watgule26 Sep '06 - 19:13 
Use 'ListView1_MouseDown()' Method to extract item to be dragged and pass the same to the 'TreeView1_DragDrop()'Method.
GeneralRe: DnD for multiple ListViewItem'smembermk-orange27 Sep '06 - 6:04 
Could you explain this more clear? Basically I do this, but I can't properly pass multiple ListViewItem’s to the DoDragDrop() method. In other words I try pass theirs as “ListView1.CheckedItems” or try to create Array with ListViewItem’s and pass it to DoDragDrop() method. But both of these methods don’t work. In “TreeView1.DragDrop” event I can’t properly extract dragged Items. Could you provide some code how to do this?
GeneralRe: DnD for multiple ListViewItem'smemberUjwal Watgule27 Sep '06 - 20:05 
[i] Drop two listview 'lstTry' and 'lstMore' on the 'frmCntryTree' form.
[ii]Comment (a)lstCust_MeasureItem,lstCust_DrawItem method of listbox
[iii] in the 'PopulateCust' method add the following code:-
 
" Dim iCount As Integer
Try
For iCount = 0 To dtCust.Rows.Count - 1
lstTry.Items.Insert(iCount, (dtCust.Rows(iCount)("ContactName").ToString))
lstMore.Items.Insert(iCount, (dtCust.Rows(iCount)("ContactName").ToString))
Next
Catch ex As Exception
Throw ex
End Try
"
 
[iv]In the 'lstTry_MouseDown' event add the following code:-
"
Dim iFound As Integer
Dim iLength As Integer
Dim strItem As String
Try
If lstTry.Items.Count > sZero Then
 
strItem = lstTry.GetItemAt(e.X, e.Y).Text
strLstItem = lstTry.GetItemAt(e.X, e.Y).Text 'lstTry.Items(lstTry.IndexFromPoint(e.X, e.Y)).ToString()
 
iFound = strItem.IndexOf("(")
If iFound > sZero Then
iLength = strItem.Length
' remove the substring starting with "(" ...
strItem = strItem.Remove(iFound, (iLength - iFound))
End If
If strItem.Trim.Length > sZero Then
DoDragDrop(strItem, DragDropEffects.All)
End If
End If
Catch ex As Exception
Throw ex
End Try
"
 
[v]In the 'lstMore_MouseDown' event add the following code:-
"
Dim iFound As Integer
Dim iLength As Integer
Dim strItem As String
Try
If lstMore.Items.Count > sZero Then
 
strItem = lstMore.GetItemAt(e.X, e.Y).Text
strLstItem = lstMore.GetItemAt(e.X, e.Y).Text 'lstTry.Items(lstTry.IndexFromPoint(e.X, e.Y)).ToString()
 
iFound = strItem.IndexOf("(")
If iFound > sZero Then
iLength = strItem.Length
' remove the substring starting with "(" ...
strItem = strItem.Remove(iFound, (iLength - iFound))
End If
If strItem.Trim.Length > sZero Then
DoDragDrop(strItem, DragDropEffects.All)
End If
End If
Catch ex As Exception
Throw ex
End Try
"
 
[vi] Run the program and you would find that u can now drag item from both the ListViews(lstTry and lstMore)and drop the same on TreeView.
 

QuestionDoing the same in ASP.Net Web ApplicationmemberMon217 Aug '06 - 14:44 
Hi Ujwal,
I want to do the same thing that you have done in this article on a Web Application. Please help me.

 
Manpreet
AnswerRe: Doing the same in ASP.Net Web ApplicationmemberUjwal Watgule21 Aug '06 - 6:15 
Yes Manpreet,you can do it in asp.net.Let me know what help u need.
QuestionRe: Doing the same in ASP.Net Web Applicationmemberhamdanimars2 Oct '06 - 2:27 
Tell me how to make it ?

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 23 May 2006
Article Copyright 2006 by Ujwal Watgule
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid