Link to home
Start Free TrialLog in
Avatar of chlade
chlade

asked on

TreeView drag/drop line drawing

I have a form with two treeviews.  I want the user to be able to drag from a node in the treeview on the left and drop in the treeview on the right and have it draw a line connecting them.  The line should appear between the treeviews (ie. from the right edge of the one on the left to the left edge of the one on the right.

I want the line to draw and redraw as I move the cursor around.  Thus, before I let go of the mouse button to draw the line, I should already see the line drawn.

I pulled my code out of the main program into a test program.  I will paste it below.  You should be able to paste this into a new project to see what my problem is.

I have been tearing my hair out for a few hours trying to figure this out.  I don't think I'm far off but I can't seem to get it.

Thanks!
Chris

Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer
    Friend WithEvents TreeView2 As System.Windows.Forms.TreeView
    Friend WithEvents TreeView1 As System.Windows.Forms.TreeView

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    Friend WithEvents Panel1 As System.Windows.Forms.Panel
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.Panel1 = New System.Windows.Forms.Panel
        Me.TreeView2 = New System.Windows.Forms.TreeView
        Me.TreeView1 = New System.Windows.Forms.TreeView
        Me.Panel1.SuspendLayout()
        Me.SuspendLayout()
        '
        'Panel1
        '
        Me.Panel1.AllowDrop = True
        Me.Panel1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.Panel1.Controls.Add(Me.TreeView2)
        Me.Panel1.Controls.Add(Me.TreeView1)
        Me.Panel1.Location = New System.Drawing.Point(8, 12)
        Me.Panel1.Name = "Panel1"
        Me.Panel1.Size = New System.Drawing.Size(396, 233)
        Me.Panel1.TabIndex = 2
        '
        'TreeView2
        '
        Me.TreeView2.AllowDrop = True
        Me.TreeView2.Dock = System.Windows.Forms.DockStyle.Right
        Me.TreeView2.Location = New System.Drawing.Point(275, 0)
        Me.TreeView2.Name = "TreeView2"
        Me.TreeView2.RightToLeft = System.Windows.Forms.RightToLeft.Yes
        Me.TreeView2.RightToLeftLayout = True
        Me.TreeView2.Size = New System.Drawing.Size(121, 233)
        Me.TreeView2.TabIndex = 5
        '
        'TreeView1
        '
        Me.TreeView1.AllowDrop = True
        Me.TreeView1.Dock = System.Windows.Forms.DockStyle.Left
        Me.TreeView1.Location = New System.Drawing.Point(0, 0)
        Me.TreeView1.Name = "TreeView1"
        Me.TreeView1.Size = New System.Drawing.Size(121, 233)
        Me.TreeView1.TabIndex = 4
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(412, 251)
        Me.Controls.Add(Me.Panel1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        Me.Panel1.ResumeLayout(False)
        Me.ResumeLayout(False)

    End Sub

#End Region

    Private startPoint As Point
    Private endPoint As Point
    Private startIndex As Integer
    Private lastIndex As Integer = -1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        For i As Integer = 1 To 50
            TreeView1.Nodes.Add("Item" & i)
            TreeView2.Nodes.Add("Item" & i)
        Next

    End Sub

    Private Sub TreeView1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles TreeView1.MouseDown

        TreeView1.SelectedNode = TreeView1.GetNodeAt(New Point(e.X, e.Y))

        If e.Button = MouseButtons.Left Then
            startPoint = New Point(TreeView1.PointToScreen(New Point( _
                 TreeView1.Width, TreeView1.SelectedNode.Bounds.Y + 8)))
            Dim LevelIndex(1) As Integer
            TreeView1.DoDragDrop(TreeView1.SelectedNode, DragDropEffects.Move)
        End If

    End Sub

    Private Sub Panel1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel1.DragOver

        ControlPaint.DrawReversibleLine(startPoint, endPoint, Panel1.BackColor)
        endPoint = New Point(e.X, e.Y)
        ControlPaint.DrawReversibleLine(startPoint, endPoint, Panel1.BackColor)

    End Sub

    Private Sub Panel1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Panel1.DragEnter

        ControlPaint.DrawReversibleLine(startPoint, endPoint, Panel1.BackColor)

    End Sub

    Private Sub Panel1_DragLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Panel1.DragLeave

        Panel1.Refresh()

    End Sub


    Private Sub TreeView2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TreeView2.DragEnter

        e.Effect = DragDropEffects.Move
        Panel1.Invalidate()
        Panel1.Refresh()

    End Sub

    Private Sub TreeView2_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles TreeView2.DragOver

        Dim targetPoint As Point = TreeView2.PointToClient(New Point(e.X, e.Y))
        TreeView2.SelectedNode = TreeView2.GetNodeAt(targetPoint)

        ControlPaint.DrawReversibleLine(startPoint, endPoint, Panel1.BackColor)
        Dim tp As New Point(TreeView2.PointToScreen(TreeView2.Location))
        endPoint = New Point(tp.X, e.Y)
        ControlPaint.DrawReversibleLine(startPoint, endPoint, Panel1.BackColor)

    End Sub

End Class
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of chlade
chlade

ASKER

Thanks.  I actually did a search when I began and found that link.  In fact I started with that, changed it to use TreeViews instead of ListBoxes, and went from there.  Unfortunately, I'm stuck and can't seem to get past my problem.  
Lolz...lemme see if I can get it to work with TreeViews then.   =\
Avatar of chlade

ASKER

I ended up working out the kinks.  Since I started with the code you originally provided, I'll just go ahead and award the points.  It was quite helpful!