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
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:
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.
If trvCntry.SelectedNode.Tag = "Y" Then
SubFolder = New TreeNode()
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()
:
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:
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.