TreeView DragDrop

G

Gary Dunne

I'm writing an app that requires drag and drop operation between a ListView
and a TreeView control. (The source is the ListView). During the drag drop
operation I want to be able to detect the target node in the treeview and
auto expand it if applicable... but after a fair bit of head scratching I
can't find any easy way to accomplish this.

I think what i really need is the equivalent of the HitTest method from the
COM version of the TreeView in VB 6 ... but the DotNet version doesn't
appear to have it.

Does anyone have a code sample of how to do this ?

Thanks

Gary
 
G

Guest

Hi Gary,

Here is some sample code that I found for doing DragDrop between 2 treeviews.

In short, I think you need the treeview.GetNodeAt(..) function to find the
target node.

///
Option Strict On
#Region "Imports Statements"
Imports System
Imports System.Drawing
Imports System.Windows.Forms
#End Region
Public Class DragDrop
Inherits Form
#Region "Entry Point"
Shared Sub Main()
Application.Run(New DragDrop())
End Sub
#End Region
#Region "Controls"
Private textboxLabel As New Label()
Private toTextBox As New TextBox()
Private fromTextBox As New TextBox()
Private treeViewLabel As New Label()
Private toTreeView As New TreeView()
Private fromTreeView As New TreeView()
Private favoriteCarsTreeNode As New TreeNode()
Private bmwTreeNode As New TreeNode()
Private porscheTreeNode As New TreeNode()
Private ferrariTreeNode As New TreeNode()
Private macLarenTreeNode As New TreeNode()
Private carsTreeNode As New TreeNode()
Private astonMartinTreeNode As New TreeNode()
Private corvetteTreeNode As New TreeNode()
Private jaguarTreeNode As New TreeNode()
Private mercedesTreeNode As New TreeNode()
Private pictureBoxLabel As New Label()
Private toPictureBox As New PictureBox()
Private fromPictureBox As New PictureBox()
Private exitButton As New Button()
#End Region
#Region "Private Fields"
Private Const ctrlPressed As Byte = 8
#End Region
#Region "Constructor"
Public Sub New()
ClientSize = New Size(430, 350)
Controls.AddRange(New Control() {textboxLabel, toTextBox, _
treeViewLabel, fromTextBox, toTreeView, fromTreeView,
pictureBoxLabel, _
toPictureBox, fromPictureBox, exitButton})
FormBorderStyle = FormBorderStyle.FixedToolWindow
Icon = New Icon(Me.GetType(), "GPS.ico")
StartPosition = FormStartPosition.CenterScreen
Text = "Drag and Drop"

With textboxLabel
.Location = New Point(10, 10)
.Size = New Size(250, 20)
.Text = "Hold Ctrl if you want to copy the text:"
End With

With toTextBox
.AllowDrop = True
.Location = New Point(10, 40)
.Size = New Size(200, 20)
.Text = "Some sample text..."
AddHandler toTextBox.MouseDown, AddressOf ToTextBoxOnMouseDown
End With

With fromTextBox
.AllowDrop = True
.Location = New Point(220, 40)
.Size = New Size(200, 20)
.Text = "This text will disappear."
AddHandler fromTextBox.DragDrop, AddressOf FromTextBoxOnDragDrop
AddHandler fromTextBox.DragEnter, AddressOf FromTextBoxOnDragEnter
End With

With treeViewLabel
.Location = New Point(10, 70)
.Size = New Size(250, 20)
.Text = "Hold Ctrl if you want to copy the tree nodes."
End With

bmwTreeNode.Text = "BMW"
porscheTreeNode.Text = "Porsche"
ferrariTreeNode.Text = "Ferrari"
macLarenTreeNode.Text = "MacLaren"

With favoriteCarsTreeNode
.Text = "Cars"
.Nodes.AddRange(New TreeNode() {bmwTreeNode, porscheTreeNode, _
ferrariTreeNode, macLarenTreeNode})
End With

astonMartinTreeNode.Text = "Aston Martin"
corvetteTreeNode.Text = "Corvette"
jaguarTreeNode.Text = "Jaguar"
mercedesTreeNode.Text = "Mercedes Benz"

With carsTreeNode
.Text = "Cars"
.Nodes.AddRange(New TreeNode() {astonMartinTreeNode,
corvetteTreeNode, _
jaguarTreeNode, mercedesTreeNode})
End With

With toTreeView
.AllowDrop = True
.Location = New Point(10, 100)
.Size = New Size(200, 100)
.Nodes.AddRange(New TreeNode() {favoriteCarsTreeNode})
AddHandler toTreeView.DragDrop, AddressOf TreeViewOnDragDrop
AddHandler toTreeView.DragEnter, AddressOf TreeViewOnDragEnter
AddHandler toTreeView.ItemDrag, AddressOf TreeViewOnItemDrag
End With

With fromTreeView
.AllowDrop = True
.Location = New Point(220, 100)
.Size = New Size(200, 100)
.Nodes.AddRange(New TreeNode() {carsTreeNode})
AddHandler fromTreeView.DragDrop, AddressOf TreeViewOnDragDrop
AddHandler fromTreeView.DragEnter, AddressOf TreeViewOnDragEnter
AddHandler fromTreeView.ItemDrag, AddressOf TreeViewOnItemDrag
End With

With pictureBoxLabel
.Location = New Point(10, 220)
.Size = New Size(250, 20)
.Text = "Hold Ctrl if you want to copy the icon."
End With

With toPictureBox
.AllowDrop = True
.BorderStyle = BorderStyle.Fixed3D
.Image = New Bitmap(Me.GetType(), "GPS.ico")
.Location = New Point(80, 250)
.Name = "toPictureBox"
.Size = New Size(50, 50)
.SizeMode = PictureBoxSizeMode.CenterImage
AddHandler toPictureBox.MouseDown, AddressOf PictureBoxOnMouseDown
AddHandler toPictureBox.DragEnter, AddressOf PictureBoxOnDragEnter
AddHandler toPictureBox.DragDrop, AddressOf PictureBoxOnDragDrop
End With

With fromPictureBox
.AllowDrop = True
.BorderStyle = BorderStyle.Fixed3D
.Location = New Point(290, 250)
.Name = "fromPictureBox"
.Size = New Size(50, 50)
.SizeMode = PictureBoxSizeMode.CenterImage
AddHandler fromPictureBox.MouseDown, AddressOf
PictureBoxOnMouseDown
AddHandler fromPictureBox.DragEnter, AddressOf
PictureBoxOnDragEnter
AddHandler fromPictureBox.DragDrop, AddressOf PictureBoxOnDragDrop
End With

With exitButton
.FlatStyle = FlatStyle.System
.Location = New Point(350, 310)
.Size = New Size(70, 30)
.Text = "E&xit"
AddHandler exitButton.Click, AddressOf ExitOnClick
End With
End Sub
#End Region
#Region "Methods"
Private Sub ToTextBoxOnMouseDown(ByVal obj As Object, _
ByVal mea As MouseEventArgs)
If mea.Button = MouseButtons.Left Then
toTextBox.SelectAll()
toTextBox.DoDragDrop(toTextBox.SelectedText,
DragDropEffects.Move Or _
DragDropEffects.Copy)
End If
End Sub
Private Sub FromTextBoxOnDragDrop(ByVal obj As Object, _
ByVal dea As DragEventArgs)
fromTextBox.Text = dea.Data.GetData(DataFormats.Text).ToString()
If (dea.KeyState And ctrlPressed) <> ctrlPressed Then
toTextBox.Text = ""
End If
End Sub
Private Sub FromTextBoxOnDragEnter(ByVal obj As Object, _
ByVal dea As DragEventArgs)
If (dea.Data.GetDataPresent(DataFormats.Text)) Then
If (dea.KeyState And ctrlPressed) = ctrlPressed Then
dea.Effect = DragDropEffects.Copy
Else
dea.Effect = DragDropEffects.Move
End If
Else
dea.Effect = DragDropEffects.None
End If
End Sub
Private Sub TreeViewOnDragDrop(ByVal obj As Object, _
ByVal dea As DragEventArgs)
Dim draggedNode As TreeNode = _
CType(dea.Data.GetData("System.Windows.Forms.TreeNode"), TreeNode)
If dea.Data.GetDataPresent("System.Windows.Forms.TreeNode", False)
Then
Dim drawingPoint As Point
Dim destinationNode As TreeNode
drawingPoint = CType(obj, TreeView).PointToClient _
(New Point(dea.X, dea.Y))
destinationNode = CType(obj, TreeView).GetNodeAt(drawingPoint)
If Not destinationNode.TreeView Is draggedNode.TreeView Then
destinationNode.Nodes.Add(CType(draggedNode.Clone, TreeNode))
destinationNode.Expand()
If (dea.KeyState And ctrlPressed) <> ctrlPressed Then
draggedNode.Remove()
End If
End If
End If
End Sub
Private Sub TreeViewOnDragEnter(ByVal obj As Object, _
ByVal dea As DragEventArgs)
If (dea.Data.GetDataPresent("System.Windows.Forms.TreeNode")) Then
If (dea.KeyState And ctrlPressed) = ctrlPressed Then
dea.Effect = DragDropEffects.Copy
Else
dea.Effect = DragDropEffects.Move
End If
Else
dea.Effect = DragDropEffects.None
End If
End Sub
Private Sub TreeViewOnItemDrag(ByVal obj As Object, _
ByVal idea As ItemDragEventArgs)
If idea.Button = MouseButtons.Left Then
DoDragDrop(idea.Item, DragDropEffects.Move Or
DragDropEffects.Copy)
End If
End Sub
Private Sub PictureBoxOnMouseDown(ByVal obj As Object, _
ByVal mea As MouseEventArgs)
If mea.Button = MouseButtons.Left Then
Dim image As PictureBox = CType(obj, PictureBox)
If Not image.Image Is Nothing Then
image.DoDragDrop(image.Image, DragDropEffects.Move Or _
DragDropEffects.Copy)
End If
End If
End Sub
Private Sub PictureBoxOnDragEnter(ByVal obj As Object, _
ByVal dea As DragEventArgs)
If (dea.Data.GetDataPresent(DataFormats.Bitmap)) Then
If (dea.KeyState And ctrlPressed) = ctrlPressed Then
dea.Effect = DragDropEffects.Copy
Else
dea.Effect = DragDropEffects.Move
End If
Else
dea.Effect = DragDropEffects.None
End If
End Sub
Private Sub PictureBoxOnDragDrop(ByVal obj As Object, _
ByVal dea As DragEventArgs)
Dim picture As PictureBox = CType(obj, PictureBox)
picture.Image = CType(dea.Data.GetData(DataFormats.Bitmap), Bitmap)
If (dea.KeyState And ctrlPressed) <> ctrlPressed Then
If picture.Name = "toPictureBox" Then
fromPictureBox.Image = Nothing
Else
toPictureBox.Image = Nothing
End If
End If
End Sub
Private Sub ExitOnClick(ByVal obj As Object, ByVal ea As EventArgs)
Application.Exit()
End Sub
#End Region
End Class
\\\

HTH
 
R

Robin Tucker

in tree dragover event:




Dim mousePos As Point

mousePos = TreeView.PointToClient(Cursor.Position)

Dim nodeOver As TreeViewNode = TreeView.GetNodeAt(mousePos)

If nodeOver Is Nothing Then
.... we aren't over a node.
Else
.... we are over a node, so determine whether we are allowed to
drag/drop
End If
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top