Solved

Drag and drop between listbox and treeview

Posted on 2011-02-28
2
1,241 Views
Last Modified: 2012-05-11
HI,
I have win form with TreeView control on itself...I made drag and drop working within treeview very well...Since the treeview hierarchy is so large (about 700 chaild nodes) i got request from users to try to make simplyfied moving chiled nodes from one parent to another in treeView hierarchy ... So I have decided to introduce ListView Control on the same form which will be loaded with child nodes related to selected parent in treeView hierarchy...
Now I face with big trouble how to make working this drag and drop from listView to treeview (i've been searching for the solution on the web for 2 days but with no success)...
Also, when I drag and drop listvie items on new location (on new parent) in treeView the same should be removed from the old position within hierarchy...
In addition please find drag and drop subs which I use for movig treView items in treeview it self....New ListView is marked as ListView1
Public Sub TreeView1_ItemDrag(ByVal sender As System.Object, _
        ByVal e As System.Windows.Forms.ItemDragEventArgs) _
        Handles TreeView1.ItemDrag

        m_tnSource = CType(e.Item, TreeNode)
        DoDragDrop(e.Item, DragDropEffects.Move)


    End Sub

    Public Sub TreeView1_DragEnter(ByVal sender As System.Object, _
        ByVal e As System.Windows.Forms.DragEventArgs) _
        Handles TreeView1.DragEnter


        If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
            True) Then

            e.Effect = DragDropEffects.Move
        Else

            e.Effect = DragDropEffects.None
        End If

    End Sub

    Public Sub TreeView1_DragOver(ByVal sender As System.Object, _
         ByVal e As System.Windows.Forms.DragEventArgs) _
        Handles TreeView1.DragOver


        If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
               True) = False Then Exit Sub


        Dim selectedTreeview As TreeView = CType(sender, TreeView)


        Dim pt As Point = _
            CType(sender, TreeView).PointToClient(New Point(e.X, e.Y))
        Dim targetNode As TreeNode = selectedTreeview.GetNodeAt(pt)


        If Not (selectedTreeview.SelectedNode Is targetNode) Then

            selectedTreeview.SelectedNode = targetNode


            Dim dropNode As TreeNode = _
                CType(e.Data.GetData("System.Windows.Forms.TreeNode"),  _
                TreeNode)

            Do Until targetNode Is Nothing
                If targetNode Is dropNode Then
                    e.Effect = DragDropEffects.None
                    Exit Sub
                End If
                targetNode = targetNode.Parent
            Loop
        End If


        e.Effect = DragDropEffects.Move


    End Sub

    Public Sub TreeView1_DragDrop(ByVal sender As System.Object, _
       ByVal e As System.Windows.Forms.DragEventArgs) _
       Handles TreeView1.DragDrop

        Dim pt As Point
        Dim tnDestination As TreeNode
        Dim tnNew As TreeNode
        Dim tnSourceParent As TreeNode

        If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", True) Then


            pt = TreeView1.PointToClient(New Point(e.X, e.Y))
            tnDestination = TreeView1.GetNodeAt(pt)

            If CTree.IsDropAllowed(m_tnSource, tnDestination) = True Then
                tnSourceParent = m_tnSource.Parent

                tnNew = CType(e.Data.GetData("System.Windows.Forms.TreeNode"), TreeNode)
                tnDestination.Nodes.Add(CType(tnNew.Clone, TreeNode))
                tnDestination.ExpandAll()
                tnNew.Remove()

            Else
                
                MsgBox("The dragged item cannot be dropped here because" & _
                       "doing so will create a circular reference.", _
                       MsgBoxStyle.Exclamation)
            End If

        End If

    End Sub

Open in new window

0
Comment
Question by:alsam
2 Comments
 
LVL 12

Accepted Solution

by:
omegaomega earned 500 total points
Comment Utility
Hello, alsam,

This will depend on how you populate the list box.  For example, if you add the child nodes directly to the list box (as shown in the example in the snippet) then the modifications required to your existing code are quite minor.  You just need to handle the Mouse_Down, Mouse_Move and Mouse_Up events as shown In the snippet.   In the example, I have added a few lines at the beginning to populate the TreeView.  I've also added an AfterSelect handler to the TreeView to populate the ListBox as nodes are selected and a line to your TreeView1_DragDrop event handler to repopulate the ListBox after the drop is completed.

If, instead of adding the TreeNodes themselves to the ListBox, you add something else (such as a text description of the TreeNode) then you will need to take additional steps to keep track of which TreeNode is being dragged.

Cheers,
Randy
p.s.  Your code uses an object property named CTree.IsDropAllowed, which I have commented out.  Be sure to uncomment this line if pasting the changes back into your own code.
Public Class Form1

    Private m_dreDragTolerance As Rectangle        '~~~ Line added.  (Drag tolerance rectangle)
    Private m_tnSource As TreeNode = Nothing

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ' Populate the TreeView.
        Dim LastFolder As TreeNode = Nothing
        For cnt As Integer = 0 To 10
            If cnt Mod 3 = 0 Then
                LastFolder = New TreeNode(cnt.ToString)
                TreeView1.Nodes.Add(LastFolder)
            Else
                Dim tvChild As New TreeNode(cnt.ToString)
                LastFolder.Nodes.Add(tvChild)
            End If
        Next cnt
    End Sub

    Public Sub TreeView1_ItemDrag(ByVal sender As System.Object, _
        ByVal e As System.Windows.Forms.ItemDragEventArgs) _
        Handles TreeView1.ItemDrag

        m_tnSource = CType(e.Item, TreeNode)
        DoDragDrop(e.Item, DragDropEffects.Move)
    End Sub

    Public Sub TreeView1_DragEnter(ByVal sender As System.Object, _
        ByVal e As System.Windows.Forms.DragEventArgs) _
        Handles TreeView1.DragEnter

        If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
            True) Then
            e.Effect = DragDropEffects.Move
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub

    Public Sub TreeView1_DragOver(ByVal sender As System.Object, _
         ByVal e As System.Windows.Forms.DragEventArgs) _
        Handles TreeView1.DragOver

        If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", _
               True) = False Then Exit Sub

        Dim selectedTreeview As TreeView = CType(sender, TreeView)
        Dim pt As Point = _
            CType(sender, TreeView).PointToClient(New Point(e.X, e.Y))
        Dim targetNode As TreeNode = selectedTreeview.GetNodeAt(pt)
        If Not (selectedTreeview.SelectedNode Is targetNode) Then
            selectedTreeview.SelectedNode = targetNode
            Dim dropNode As TreeNode = _
                CType(e.Data.GetData("System.Windows.Forms.TreeNode"), _
                TreeNode)
            Do Until targetNode Is Nothing
                If targetNode Is dropNode Then
                    e.Effect = DragDropEffects.None
                    Exit Sub
                End If
                targetNode = targetNode.Parent
            Loop
        End If
        e.Effect = DragDropEffects.Move
    End Sub

    Public Sub TreeView1_DragDrop(ByVal sender As System.Object, _
       ByVal e As System.Windows.Forms.DragEventArgs) _
       Handles TreeView1.DragDrop

        Dim pt As Point
        Dim tnDestination As TreeNode
        Dim tnNew As TreeNode
        Dim tnSourceParent As TreeNode

        If e.Data.GetDataPresent("System.Windows.Forms.TreeNode", True) Then
            pt = TreeView1.PointToClient(New Point(e.X, e.Y))
            tnDestination = TreeView1.GetNodeAt(pt)
            ' ''If CTree.IsDropAllowed(m_tnSource, tnDestination) = True Then   '~~~ Line removed, because CTree is not available.
            If True Then
                tnSourceParent = m_tnSource.Parent

                tnNew = CType(e.Data.GetData("System.Windows.Forms.TreeNode"), TreeNode)
                tnDestination.Nodes.Add(CType(tnNew.Clone, TreeNode))
                tnDestination.ExpandAll()
                tnNew.Remove()
                RepopulateListBox()         '~~~ Line added.
            Else
                MsgBox("The dragged item cannot be dropped here because" & _
                       "doing so will create a circular reference.", _
                       MsgBoxStyle.Exclamation)
            End If
        End If
    End Sub

    Private Sub TreeView1_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles TreeView1.AfterSelect
        RepopulateListBox()
    End Sub

    Private Sub RepopulateListBox()
        Me.ListBox1.Items.Clear()
        If (TreeView1.SelectedNode Is Nothing) Then Exit Sub
        For Each tnChild As TreeNode In TreeView1.SelectedNode.Nodes
            Me.ListBox1.Items.Add(tnChild)
        Next tnChild
    End Sub

    Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
        ' Prepare for initiation of a drag operation by defining the tolerance rectangle.
        Dim dszTolerance As Size = SystemInformation.DragSize
        m_dreDragTolerance = New Rectangle(e.X - CInt(dszTolerance.Width / 2), _
                                          e.Y - CInt(dszTolerance.Height / 2), _
                                          dszTolerance.Width, dszTolerance.Height)
    End Sub

    Private Sub ListBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseMove

        If (e.Button <> Windows.Forms.MouseButtons.Left OrElse ListBox1.SelectedItem Is Nothing) Then Exit Sub

        If (Rectangle.op_Inequality(m_dreDragTolerance, Rectangle.Empty) AndAlso _
            Not m_dreDragTolerance.Contains(e.X, e.Y)) Then
            m_dreDragTolerance = Rectangle.Empty
            ' Start the drag operation.
            m_tnSource = CType(ListBox1.SelectedItem, TreeNode)
            ListBox1.DoDragDrop(m_tnSource, DragDropEffects.Move)
        End If

    End Sub

    Private Sub ListBox1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseUp
        m_dreDragTolerance = Rectangle.Empty
    End Sub

End Class

Open in new window

0
 
LVL 1

Author Closing Comment

by:alsam
Comment Utility
Hi,
this is clear A+
Thank you for your time and effort...
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now