【原创】教你快速实现TreeView节点拖放(Drag&Drop)
Code
1using System;
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Linq;
7using System.Text;
8using System.Windows.Forms;
9
10namespace MyTree
11{
12 public partial class Form2 : Form
13 {
14 // Node being dragged
15 private TreeNode dragNode = null;
16
17 // Temporary drop node for selection
18 private TreeNode tempDropNode = null;
19
20 // Timer for scrolling
21 private Timer timer = new Timer();
22
23 public Form2()
24 {
25 InitializeComponent();
26
27 //bind data to the treeView
28 BindTreeView mt = new BindTreeView();
29 mt.SetSqlconnstr("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\App_Data\\MemuTreeDB.mdf;Integrated Security=True;User Instance=True");
30 mt.GetDataSet("tbTree");
31 mt.BindTV(treeView1);
32
33 this.treeView1.ExpandAll();
34
35 timer.Interval = 200;
36 timer.Tick += new EventHandler(timer_Tick);
37 }
38
39 private void treeView_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
40 {
41 // Get drag node and select it
42 this.dragNode = (TreeNode)e.Item;
43 this.treeView1.SelectedNode = this.dragNode;
44/**//**/
45 // Reset image list used for drag image
46 this.imageListDrag.Images.Clear();
47 this.imageListDrag.ImageSize = new Size(this.dragNode.Bounds.Size.Width + this.treeView1.Indent, this.dragNode.Bounds.Height);
48
49 // Create new bitmap
50 // This bitmap will contain the tree node image to be dragged
51 Bitmap bmp = new Bitmap(this.dragNode.Bounds.Width + this.treeView1.Indent, this.dragNode.Bounds.Height);
52
53 // Get graphics from bitmap
54 Graphics gfx = Graphics.FromImage(bmp);
55
56 // Draw node icon into the bitmap
57 gfx.DrawImage(this.imageListTreeView.Images[0], 0, 0);
58
59 // Draw node label into bitmap
60 gfx.DrawString(this.dragNode.Text,
61 this.treeView1.Font,
62 new SolidBrush(this.treeView1.ForeColor),
63 (float)this.treeView1.Indent, 1.0f);
64
65 // Add bitmap to imagelist
66 this.imageListDrag.Images.Add(bmp);
67
68 // Get mouse position in client coordinates
69 Point p = this.treeView1.PointToClient(Control.MousePosition);
70
71 // Compute delta between mouse position and node bounds
72 int dx = p.X + this.treeView1.Indent - this.dragNode.Bounds.Left;
73 int dy = p.Y - this.dragNode.Bounds.Top;
74
75 // Begin dragging image
76 if (DragHelper.ImageList_BeginDrag(this.imageListDrag.Handle, 0, dx, dy))
77 {
78 // Begin dragging
79 this.treeView1.DoDragDrop(bmp, DragDropEffects.Move);
80 // End dragging image
81 DragHelper.ImageList_EndDrag();
82 }
83
84 }
85
86 private void treeView1_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
87 {
88 // Compute drag position and move image
89 Point formP = this.PointToClient(new Point(e.X, e.Y));
90 DragHelper.ImageList_DragMove(formP.X - this.treeView1.Left, formP.Y - this.treeView1.Top);
91
92 // Get actual drop node
93 TreeNode dropNode = this.treeView1.GetNodeAt(this.treeView1.PointToClient(new Point(e.X, e.Y)));
94 if (dropNode == null)
95 {
96 e.Effect = DragDropEffects.None;
97 return;
98 }
99
100 e.Effect = DragDropEffects.Move;
101
102 // if mouse is on a new node select it
103 if (this.tempDropNode != dropNode)
104 {
105 DragHelper.ImageList_DragShowNolock(false);
106 this.treeView1.SelectedNode = dropNode;
107 DragHelper.ImageList_DragShowNolock(true);
108 tempDropNode = dropNode;
109 }
110
111 // Avoid that drop node is child of drag node
112 TreeNode tmpNode = dropNode;
113 while (tmpNode.Parent != null)
114 {
115 if (tmpNode.Parent == this.dragNode) e.Effect = DragDropEffects.None;
116 tmpNode = tmpNode.Parent;
117 }
118 }
119
120 private void treeView1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
121 {
122 // Unlock updates
123 DragHelper.ImageList_DragLeave(this.treeView1.Handle);
124
125 // Get drop node
126 TreeNode dropNode = this.treeView1.GetNodeAt(this.treeView1.PointToClient(new Point(e.X, e.Y)));
127
128 // If drop node isn't equal to drag node, add drag node as child of drop node
129 if (this.dragNode != dropNode)
130 {
131 // Remove drag node from parent
132 if (this.dragNode.Parent == null)
133 {
134 this.treeView1.Nodes.Remove(this.dragNode);
135 }
136 else
137 {
138 this.dragNode.Parent.Nodes.Remove(this.dragNode);
139 }
140
141 // Add drag node to drop node
142 dropNode.Nodes.Add(this.dragNode);
143 dropNode.ExpandAll();
144
145 // Set drag node to null
146 this.dragNode = null;
147
148 // Disable scroll timer
149 this.timer.Enabled = false;
150 }
151 }
152
153 private void treeView1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
154 {
155 DragHelper.ImageList_DragEnter(this.treeView1.Handle, e.X - this.treeView1.Left,
156 e.Y - this.treeView1.Top);
157
158 // Enable timer for scrolling dragged item
159 this.timer.Enabled = true;
160 }
161
162 private void treeView1_DragLeave(object sender, System.EventArgs e)
163 {
164 DragHelper.ImageList_DragLeave(this.treeView1.Handle);
165
166 // Disable timer for scrolling dragged item
167 this.timer.Enabled = false;
168 }
169
170 private void treeView1_GiveFeedback(object sender, System.Windows.Forms.GiveFeedbackEventArgs e)
171 {
172 if (e.Effect == DragDropEffects.Move)
173 {
174 // Show pointer cursor while dragging
175 e.UseDefaultCursors = false;
176 this.treeView1.Cursor = Cursors.Default;
177 }
178 else e.UseDefaultCursors = true;
179
180 }
181
182 private void timer_Tick(object sender, EventArgs e)
183 {
184 // get node at mouse position
185 Point pt = PointToClient(Control.MousePosition);
186 TreeNode node = this.treeView1.GetNodeAt(pt);
187
188 if (node == null) return;
189
190 // if mouse is near to the top, scroll up
191 if (pt.Y < 30)
192 {
193 // set actual node to the upper one
194 if (node.PrevVisibleNode != null)
195 {
196 node = node.PrevVisibleNode;
197
198 // hide drag image
199 DragHelper.ImageList_DragShowNolock(false);
200 // scroll and refresh
201 node.EnsureVisible();
202 this.treeView1.Refresh();
203 // show drag image
204 DragHelper.ImageList_DragShowNolock(true);
205
206 }
207 }
208 // if mouse is near to the bottom, scroll down
209 else if (pt.Y > this.treeView1.Size.Height - 30)
210 {
211 if (node.NextVisibleNode != null)
212 {
213 node = node.NextVisibleNode;
214
215 DragHelper.ImageList_DragShowNolock(false);
216 node.EnsureVisible();
217 this.treeView1.Refresh();
218 DragHelper.ImageList_DragShowNolock(true);
219 }
220 }
221 }
222
223 private void Form2_Load(object sender, EventArgs e)
224 {
225
226 }
227 }
228}
229
1using System;
2using System.Collections.Generic;
3using System.ComponentModel;
4using System.Data;
5using System.Drawing;
6using System.Linq;
7using System.Text;
8using System.Windows.Forms;
9
10namespace MyTree
11{
12 public partial class Form2 : Form
13 {
14 // Node being dragged
15 private TreeNode dragNode = null;
16
17 // Temporary drop node for selection
18 private TreeNode tempDropNode = null;
19
20 // Timer for scrolling
21 private Timer timer = new Timer();
22
23 public Form2()
24 {
25 InitializeComponent();
26
27 //bind data to the treeView
28 BindTreeView mt = new BindTreeView();
29 mt.SetSqlconnstr("Data Source=.\\SQLEXPRESS;AttachDbFilename=|DataDirectory|\\App_Data\\MemuTreeDB.mdf;Integrated Security=True;User Instance=True");
30 mt.GetDataSet("tbTree");
31 mt.BindTV(treeView1);
32
33 this.treeView1.ExpandAll();
34
35 timer.Interval = 200;
36 timer.Tick += new EventHandler(timer_Tick);
37 }
38
39 private void treeView_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
40 {
41 // Get drag node and select it
42 this.dragNode = (TreeNode)e.Item;
43 this.treeView1.SelectedNode = this.dragNode;
44/**//**/
45 // Reset image list used for drag image
46 this.imageListDrag.Images.Clear();
47 this.imageListDrag.ImageSize = new Size(this.dragNode.Bounds.Size.Width + this.treeView1.Indent, this.dragNode.Bounds.Height);
48
49 // Create new bitmap
50 // This bitmap will contain the tree node image to be dragged
51 Bitmap bmp = new Bitmap(this.dragNode.Bounds.Width + this.treeView1.Indent, this.dragNode.Bounds.Height);
52
53 // Get graphics from bitmap
54 Graphics gfx = Graphics.FromImage(bmp);
55
56 // Draw node icon into the bitmap
57 gfx.DrawImage(this.imageListTreeView.Images[0], 0, 0);
58
59 // Draw node label into bitmap
60 gfx.DrawString(this.dragNode.Text,
61 this.treeView1.Font,
62 new SolidBrush(this.treeView1.ForeColor),
63 (float)this.treeView1.Indent, 1.0f);
64
65 // Add bitmap to imagelist
66 this.imageListDrag.Images.Add(bmp);
67
68 // Get mouse position in client coordinates
69 Point p = this.treeView1.PointToClient(Control.MousePosition);
70
71 // Compute delta between mouse position and node bounds
72 int dx = p.X + this.treeView1.Indent - this.dragNode.Bounds.Left;
73 int dy = p.Y - this.dragNode.Bounds.Top;
74
75 // Begin dragging image
76 if (DragHelper.ImageList_BeginDrag(this.imageListDrag.Handle, 0, dx, dy))
77 {
78 // Begin dragging
79 this.treeView1.DoDragDrop(bmp, DragDropEffects.Move);
80 // End dragging image
81 DragHelper.ImageList_EndDrag();
82 }
83
84 }
85
86 private void treeView1_DragOver(object sender, System.Windows.Forms.DragEventArgs e)
87 {
88 // Compute drag position and move image
89 Point formP = this.PointToClient(new Point(e.X, e.Y));
90 DragHelper.ImageList_DragMove(formP.X - this.treeView1.Left, formP.Y - this.treeView1.Top);
91
92 // Get actual drop node
93 TreeNode dropNode = this.treeView1.GetNodeAt(this.treeView1.PointToClient(new Point(e.X, e.Y)));
94 if (dropNode == null)
95 {
96 e.Effect = DragDropEffects.None;
97 return;
98 }
99
100 e.Effect = DragDropEffects.Move;
101
102 // if mouse is on a new node select it
103 if (this.tempDropNode != dropNode)
104 {
105 DragHelper.ImageList_DragShowNolock(false);
106 this.treeView1.SelectedNode = dropNode;
107 DragHelper.ImageList_DragShowNolock(true);
108 tempDropNode = dropNode;
109 }
110
111 // Avoid that drop node is child of drag node
112 TreeNode tmpNode = dropNode;
113 while (tmpNode.Parent != null)
114 {
115 if (tmpNode.Parent == this.dragNode) e.Effect = DragDropEffects.None;
116 tmpNode = tmpNode.Parent;
117 }
118 }
119
120 private void treeView1_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
121 {
122 // Unlock updates
123 DragHelper.ImageList_DragLeave(this.treeView1.Handle);
124
125 // Get drop node
126 TreeNode dropNode = this.treeView1.GetNodeAt(this.treeView1.PointToClient(new Point(e.X, e.Y)));
127
128 // If drop node isn't equal to drag node, add drag node as child of drop node
129 if (this.dragNode != dropNode)
130 {
131 // Remove drag node from parent
132 if (this.dragNode.Parent == null)
133 {
134 this.treeView1.Nodes.Remove(this.dragNode);
135 }
136 else
137 {
138 this.dragNode.Parent.Nodes.Remove(this.dragNode);
139 }
140
141 // Add drag node to drop node
142 dropNode.Nodes.Add(this.dragNode);
143 dropNode.ExpandAll();
144
145 // Set drag node to null
146 this.dragNode = null;
147
148 // Disable scroll timer
149 this.timer.Enabled = false;
150 }
151 }
152
153 private void treeView1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
154 {
155 DragHelper.ImageList_DragEnter(this.treeView1.Handle, e.X - this.treeView1.Left,
156 e.Y - this.treeView1.Top);
157
158 // Enable timer for scrolling dragged item
159 this.timer.Enabled = true;
160 }
161
162 private void treeView1_DragLeave(object sender, System.EventArgs e)
163 {
164 DragHelper.ImageList_DragLeave(this.treeView1.Handle);
165
166 // Disable timer for scrolling dragged item
167 this.timer.Enabled = false;
168 }
169
170 private void treeView1_GiveFeedback(object sender, System.Windows.Forms.GiveFeedbackEventArgs e)
171 {
172 if (e.Effect == DragDropEffects.Move)
173 {
174 // Show pointer cursor while dragging
175 e.UseDefaultCursors = false;
176 this.treeView1.Cursor = Cursors.Default;
177 }
178 else e.UseDefaultCursors = true;
179
180 }
181
182 private void timer_Tick(object sender, EventArgs e)
183 {
184 // get node at mouse position
185 Point pt = PointToClient(Control.MousePosition);
186 TreeNode node = this.treeView1.GetNodeAt(pt);
187
188 if (node == null) return;
189
190 // if mouse is near to the top, scroll up
191 if (pt.Y < 30)
192 {
193 // set actual node to the upper one
194 if (node.PrevVisibleNode != null)
195 {
196 node = node.PrevVisibleNode;
197
198 // hide drag image
199 DragHelper.ImageList_DragShowNolock(false);
200 // scroll and refresh
201 node.EnsureVisible();
202 this.treeView1.Refresh();
203 // show drag image
204 DragHelper.ImageList_DragShowNolock(true);
205
206 }
207 }
208 // if mouse is near to the bottom, scroll down
209 else if (pt.Y > this.treeView1.Size.Height - 30)
210 {
211 if (node.NextVisibleNode != null)
212 {
213 node = node.NextVisibleNode;
214
215 DragHelper.ImageList_DragShowNolock(false);
216 node.EnsureVisible();
217 this.treeView1.Refresh();
218 DragHelper.ImageList_DragShowNolock(true);
219 }
220 }
221 }
222
223 private void Form2_Load(object sender, EventArgs e)
224 {
225
226 }
227 }
228}
229
DragerHepler类:
Code
1using System;
2using System.Runtime.InteropServices;
3
4namespace MyTree
5{
6 public class DragHelper
7 {
8 [DllImport("comctl32.dll")]
9 public static extern bool InitCommonControls();
10
11 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
12 public static extern bool ImageList_BeginDrag(IntPtr himlTrack, int
13 iTrack, int dxHotspot, int dyHotspot);
14
15 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
16 public static extern bool ImageList_DragMove(int x, int y);
17
18 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
19 public static extern void ImageList_EndDrag();
20
21 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
22 public static extern bool ImageList_DragEnter(IntPtr hwndLock, int x, int y);
23
24 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
25 public static extern bool ImageList_DragLeave(IntPtr hwndLock);
26
27 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
28 public static extern bool ImageList_DragShowNolock(bool fShow);
29
30 static DragHelper()
31 {
32 InitCommonControls();
33 }
34 }
35}
36
1using System;
2using System.Runtime.InteropServices;
3
4namespace MyTree
5{
6 public class DragHelper
7 {
8 [DllImport("comctl32.dll")]
9 public static extern bool InitCommonControls();
10
11 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
12 public static extern bool ImageList_BeginDrag(IntPtr himlTrack, int
13 iTrack, int dxHotspot, int dyHotspot);
14
15 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
16 public static extern bool ImageList_DragMove(int x, int y);
17
18 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
19 public static extern void ImageList_EndDrag();
20
21 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
22 public static extern bool ImageList_DragEnter(IntPtr hwndLock, int x, int y);
23
24 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
25 public static extern bool ImageList_DragLeave(IntPtr hwndLock);
26
27 [DllImport("comctl32.dll", CharSet=CharSet.Auto)]
28 public static extern bool ImageList_DragShowNolock(bool fShow);
29
30 static DragHelper()
31 {
32 InitCommonControls();
33 }
34 }
35}
36
能力有限,希望高手们不吝赐教!^_^
宠辱不惊,闲看庭前花开花落;去留无意,漫随天外云卷云舒。