【原创】TreeView控件实现拖拉、添加以及删除结点操作类库
Code
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6using System.Collections;
7using System.ComponentModel;
8using System.Data;
9using System.Diagnostics;
10using System.Drawing;//Point
11using System.Windows.Forms;//TreeNode
12
13
14namespace upLibrary.upControls
15{
16 /**//// <summary>
17 /// 实现了拖放操作处理,并且每一个结点的添加和移除都能引发事件的TreeView。
18 /// </summary>
19
20 public class upTreeViewBase : System.Windows.Forms.TreeView
21 {
22 private System.ComponentModel.Container components = null;
23 private TreeNode _DragNode;
24 private bool _MoveNode = false;
25 private bool _CopyNode = false;
26 //private bool _CanDropDrag = false;
27
28 /**//// <summary>
29 /// 删除节点事件句柄(sender 是父结点或为空,e.Node是子结点)
30 /// </summary>
31
32 public delegate void NodeDeleteHandler(object Sender, upLibrary.upControls.TreeNodeEventArgs e);
33
34 /**//// <summary>
35 /// 增加节点事件句柄(sender 是父结点或为空,e.Node是子结点)
36 /// </summary>
37
38 public delegate void NodeAddHandler(object Sender, upLibrary.upControls.TreeNodeEventArgs e);
39
40 /**//// <summary>
41 /// 在删除或增加节点之间浏览子节点事件句柄(sender 是父结点或为空,e.Node是子结点)
42 /// </summary>
43
44 public delegate void BrowseTreeNodesEventHandler(object Sender, TreeNodeEventArgs e);
45
46 /**//// <summary>
47 /// 在拖放操作中改变父结点事件句柄(sender 是父结点或为空,e.Node是子结点)
48 /// </summary>
49
50 public delegate void ParentChangByDrapDropHandler(object Sender, TreeNodeEventArgs e);
51
52 控件事件声明#region 控件事件声明
53
54 [Description("在拖放操作中改变结点的父之前发生此事件")]
55
56 public event ParentChangByDrapDropHandler ParentChangingByDrapDrop;
57
58 [Description("在拖放操作中改变了结点的父之后发生此事件")]
59
60 public event ParentChangByDrapDropHandler ParentChangedByDrapDrop;
61
62 [Description("sender所代表的节点将被移除,通常在移动拖放操作之前后发生,或树已加载后再移除之前发生")]
63
64 public event NodeDeleteHandler NodeDeleting;
65
66 [Description("sender所代表的节点将被添加,通常在移动或复制拖放操作完成后发生,或树已加载后再新增之前发生")]
67
68 public event NodeAddHandler NodeAdding;
69
70 [Description("sender所代表的节点被移除,通常在移动拖放操作完成后发生,或树已加载后再移除节点后发生")]
71
72 public event NodeDeleteHandler NodeDeleted;
73
74 [Description("sender所代表的节点被添加,通常在移动或复制拖放操作完成后发生,或树已加载后再新增节点后发生")]
75
76 public event NodeAddHandler NodeAdded;
77
78 [Description("当调用BrowseNodes时从最低层开始遍历到指定node时发生此事件")]
79
80 public event BrowseTreeNodesEventHandler InverseBrowseTreeNodes;
81
82 [Description("向下遍历到指定node时发生此事件")]
83
84 public event BrowseTreeNodesEventHandler DownBrowseTreeNodes;
85
86 #endregion
87
88 public upTreeViewBase()
89 {
90 InitializeComponent();
91 }
92
93 组件设计器生成的代码#region 组件设计器生成的代码
94
95 /**//// <summary>
96 /// 设计器支持所需的方法 - 不要使用代码编辑器修改
97 /// 此方法的内容。
98 /// </summary>
99
100 private void InitializeComponent()
101 {
102 components = new System.ComponentModel.Container();
103 }
104
105 #endregion
106
107 "拖放相关"#region "拖放相关"
108
109 /**//// <summary>
110 /// 是否移动型拖放
111 /// </summary>
112
113 public bool CanMoveNode
114 {
115 get { return _MoveNode; }
116 set
117 {
118 this.ItemDrag -= new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);
119 this.DragEnter -= new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);
120 this.DragDrop -= new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);
121 _MoveNode = value;
122 if (_MoveNode)
123 {
124 this.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);
125 this.DragEnter += new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);
126 this.DragDrop += new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);
127 }
128 }
129 }
130
131 /**//// <summary>
132 /// 是否复制型拖放
133 /// </summary>
134
135 public bool CanCopyNode
136 {
137 get { return _CopyNode; }
138 set
139 {
140 this.ItemDrag -= new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);
141 this.DragEnter -= new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);
142 this.DragDrop -= new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);
143 _CopyNode = value;
144 if (_CopyNode)
145 {
146 this.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);
147 this.DragEnter += new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);
148 this.DragDrop += new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);
149 }
150 }
151 }
152
153 /**//// <summary>
154 /// 开始拖放
155 /// </summary>
156 /// <param name="sender"></param>
157 /// <param name="e"></param>
158
159 protected void TreeView_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
160 {
161 this._DragNode = (TreeNode)e.Item;
162 string strItem = e.Item.ToString();
163 if (_CopyNode && _MoveNode)
164 DoDragDrop(strItem, DragDropEffects.Move | DragDropEffects.Copy);
165 else if (_CopyNode)
166 DoDragDrop(strItem, DragDropEffects.Copy);
167 else if (_MoveNode)
168 DoDragDrop(strItem, DragDropEffects.Move);
169 }
170
171 /**//// <summary>
172 /// 拖入到控件边界内时
173 /// </summary>
174 /// <param name="sender"></param>
175 /// <param name="e"></param>
176
177 protected void TreeView_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
178 {
179 if (e.Data.GetDataPresent(DataFormats.Text))
180 {
181 if ((e.KeyState & 4) == 4 && (e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
182 e.Effect = DragDropEffects.Move; // SHIFT KeyState for move.
183 else if ((e.KeyState & 8) == 8 && (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
184 e.Effect = DragDropEffects.Copy; // CTRL KeyState for copy.
185 else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
186 e.Effect = DragDropEffects.Move; // By default, the drop action should be move, if allowed.
187 else
188 e.Effect = DragDropEffects.None;
189 }
190 else
191 e.Effect = DragDropEffects.None;
192 }
193
194 /**//// <summary>
195 /// 拖放完成
196 /// </summary>
197 /// <param name="sender"></param>
198 /// <param name="e"></param>
199
200 protected void TreeView_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
201 {
202 upLibrary.upControls.TreeNodeEventArgs args = null;
203 bool cancel = false;
204 Point Position = new Point(e.X, e.Y);
205 Position = this.PointToClient(Position);
206 TreeNode DropNode = this.GetNodeAt(Position); //承载结点
207 if (_DragNode.Parent == DropNode) return; //没有变嘛
208 TreeNode oldparent = _DragNode.Parent;
209
210 if ((e.Effect & DragDropEffects.Move) == DragDropEffects.Move) //如果是移动型就只是改一下父结点
211 {
212 if (ParentChangingByDrapDrop != null)
213 {
214 args = new upLibrary.upControls.TreeNodeEventArgs(_DragNode, oldparent, DropNode, TreeNodeOperateType.Modify, ref cancel);
215 ParentChangingByDrapDrop(this, args);
216 if (args.Cancel == true) return;
217 }
218 _DragNode.Remove();
219
220 if (DropNode != null)
221 DropNode.Nodes.Add(_DragNode); //如果树节点位于根级别,Parent 属性即为空引用
222 else
223 this.Nodes.Add(_DragNode);
224
225 if (ParentChangedByDrapDrop != null)
226 {
227 args = new upLibrary.upControls.TreeNodeEventArgs(_DragNode, oldparent, DropNode, TreeNodeOperateType.Modify, ref cancel);
228 ParentChangedByDrapDrop(this, args);
229 }
230 }
231 else //否则是复制型的话则要在承载结点处新增结点
232 {
233 TreeNode tNode = (TreeNode)_DragNode.Clone(); //是复制型的当然要新做一个啦,复制的部分包括克隆的树节点及其以下的树结构
234 this.AddNode(DropNode, tNode); //tNode及其子node都会在事件中去加入
235 }
236 }
237
238 #endregion
239
240 "增加和移除Node并引发事件"#region "增加和移除Node并引发事件"
241
242 /**//// <summary>
243 /// 加一个新Node至指定的上级Node
244 /// </summary>
245 /// <param name="newParent"></param>
246 /// <param name="nodeText"></param>
247 /// <returns>表示成功与否</returns>
248
249 public bool AddNode(TreeNode newParent, string nodeText)
250 {
251 return AddNode(newParent, new TreeNode(nodeText));
252 }
253
254 /**//// <summary>
255 /// 加一个Node至指定的上级Node
256 /// </summary>
257 /// <param name="newParent"></param>
258 /// <param name="node"></param>
259 /// <returns>表示成功与否</returns>
260
261 public bool AddNode(TreeNode newParent,TreeNode node)
262 {
263 bool cancel = false;
264 if (node != null)
265 {
266 this.DownBrowseTreeNodes += new BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByAdd);
267 TreeNodeEventArgs args = new TreeNodeEventArgs(node, node.Parent, newParent, TreeNodeOperateType.AddNew, ref cancel);
268 this.OnAdownBrowseTreeNodes(args); //让在事件中去一级级地处理
269 this.DownBrowseTreeNodes -= new BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByAdd);
270 }
271 return !cancel;
272 }
273
274 private void upTreeViewBase_BrowseTreeNodesByAdd(object Sender, TreeNodeEventArgs e)
275 {
276 if (e.OperateType == TreeNodeOperateType.AddNew)
277 {
278 if (this.NodeAdding != null)
279 {
280 NodeAdding(this, e);
281 if (e.Cancel) return;
282 }
283 e.Node.Remove();
284 if (e.NewParent != null)
285 e.NewParent.Nodes.Add(e.Node);
286 else
287 this.Nodes.Add(e.Node);
288 if (this.NodeAdded != null)
289 NodeAdded(this, e);
290 }
291 }
292
293 /**//// <summary>
294 /// 删除用户选定的当前Node
295 /// </summary>
296 /// <returns>表示成功与否</returns>
297
298 public bool DeleteNode()
299 {
300 TreeNode node = this.SelectedNode;
301 if (node != null)
302 {
303 return DeleteNode(node);
304 }
305 return false;
306 }
307
308 /**//// <summary>
309 /// 删除参数指定的Node及其子Node,从最低层开始,并在删除Node之前后分别引发事件NodeDeleting 和 NodeDeleted
310 /// </summary>
311 /// <param name="node"></param>
312 /// <returns>表示成功与否</returns>
313
314 public bool DeleteNode(TreeNode node)
315 {
316 bool cancel = false;
317 if (node != null)
318 {
319 this.InverseBrowseTreeNodes += new BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByDelete);
320 TreeNodeEventArgs args = new TreeNodeEventArgs(node, node.Parent, null, TreeNodeOperateType.Delete, ref cancel);
321 this.OnInverseBrowseTreeNodes(args); //让在事件中去一级级地处理
322 this.InverseBrowseTreeNodes -= new BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByDelete);
323 }
324 return !cancel;
325 }
326
327 private void upTreeViewBase_BrowseTreeNodesByDelete(object Sender, TreeNodeEventArgs e)
328 {
329 if (e.OperateType == TreeNodeOperateType.Delete)
330 {
331 if (this.NodeDeleting != null)
332 {
333 NodeDeleting(this, e);
334 if (e.Cancel) return;
335 }
336 e.Node.Remove();
337 if (this.NodeDeleted != null)
338 NodeDeleted(this, e);
339 }
340 }
341
342 #endregion
343
344 遍历并引发事件#region 遍历并引发事件
345
346 /**//// <summary>
347 /// 逆向遍历参数NODEX代表的节点及其所有子节点,从最底层起一层一层地引发BrowseChildNode事件
348 /// </summary>
349
350 protected void OnInverseBrowseTreeNodes(TreeNodeEventArgs args)
351 {
352 bool cancel = false;
353 TreeNode ChildNode = null, BrotherNode = null;
354 TreeNode Nodex = args.Node;
355 if (Nodex == null) return;
356
357 if (Nodex.Nodes.Count > 0)
358 {
359 ChildNode = Nodex.Nodes[0]; //能执行到此,表示有子节点
360 while (ChildNode != null && !args.Cancel) //兄弟节点可能有多个
361 {
362 BrotherNode = ChildNode.NextNode;
363 TreeNodeEventArgs arg = new TreeNodeEventArgs(ChildNode, ChildNode.Parent, ChildNode.Parent, args.OperateType, ref cancel);
364 OnInverseBrowseTreeNodes(arg);
365 args.Cancel = arg.Cancel;
366 if (arg.Cancel) return;
367 ChildNode = BrotherNode;
368 }
369 }
370
371 if (!args.Cancel) //如果下一级的事件中指定了取消,就不引发本级的事件了
372 {
373 if (InverseBrowseTreeNodes != null)
374 InverseBrowseTreeNodes(this, args); //当没有子节点时,该节点就是末节,在事件中去处理吧,
375 }
376 }
377
378 /**//// <summary>
379 /// 正向遍历参数NODEX代表的节点及其所有子节点,在事件中的操作不可逆,Cancel为真只能停止遍历
380 /// </summary>
381
382 protected void OnAdownBrowseTreeNodes(TreeNodeEventArgs args)
383 {
384 bool cancel = false;
385 TreeNode ChildNode = null, BrotherNode = null;
386 TreeNode Nodex = args.Node;
387
388 if (Nodex != null)
389 {
390 if (DownBrowseTreeNodes != null)
391 DownBrowseTreeNodes(this, args); //首先处理自己
392 if (args.Cancel) return; //要求取消,不用管下一级了
393 if (Nodex.Nodes.Count <= 0) return; //根本就没有下一级了
394
395 ChildNode = Nodex.Nodes[0]; //能执行到此,表示有子节点
396 while (ChildNode != null && !args.Cancel) //兄弟节点可能有多个
397 {
398 BrotherNode = ChildNode.NextNode;
399 TreeNodeEventArgs arg = new TreeNodeEventArgs(ChildNode, ChildNode.Parent, ChildNode.Parent, args.OperateType, ref cancel);
400 OnAdownBrowseTreeNodes(arg);
401 args.Cancel = arg.Cancel;
402 if (arg.Cancel) return;
403 ChildNode = BrotherNode;
404 }
405 }
406 }
407
408 #endregion
409 }
410
411 /**//// <summary>
412 /// 遍历指定的node及其子node时的操作类型
413 /// </summary>
414
415 public enum TreeNodeOperateType
416 {
417 BrowseOnly = 1, AddNew, Modify, Delete
418 }
419
420 public class TreeNodeEventArgs : System.EventArgs
421 {
422 private TreeNode _Node, _OldParent, _NewParent;
423 private bool _Cancel;
424 private TreeNodeOperateType _OperateType;
425
426 /**//// <summary>
427 /// 使用此事件数据时,Sender 应是Node的Parent
428 /// </summary>
429 /// <param name="Node">要加入到Sender所代表的Nodes的Node</param>
430 /// <param name="OperateType">发起遍历的操作类型</param>
431 /// <param name="Cancel">在事件处理中是否要求出污</param>
432
433 public TreeNodeEventArgs(TreeNode Node, TreeNode oldParent, TreeNode newParent, TreeNodeOperateType OperateType, ref bool Cancel)
434 : base()
435 {
436
437 _OldParent = oldParent;
438
439 _NewParent = newParent;
440
441 _Node = Node;
442
443 _Cancel = Cancel;
444
445 _OperateType = OperateType;
446
447 }
448
449 public TreeNode OldParent
450 {
451
452 get { return _OldParent; }
453
454 set { _OldParent = value; }
455
456 }
457
458 public TreeNode NewParent
459 {
460
461 get { return _NewParent; }
462
463 set { _NewParent = value; }
464
465 }
466
467 public TreeNode Node
468 {
469
470 get { return _Node; }
471
472 set { _Node = value; }
473
474 }
475
476 public TreeNodeOperateType OperateType
477 {
478
479 get { return _OperateType; }
480
481 set { _OperateType = value; }
482
483 }
484
485 public bool Cancel
486 {
487
488 get
489 {
490
491 return _Cancel;
492
493 }
494
495 set
496 {
497
498 _Cancel = value;
499
500 }
501
502 }
503
504 }
505
506}
507
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5
6using System.Collections;
7using System.ComponentModel;
8using System.Data;
9using System.Diagnostics;
10using System.Drawing;//Point
11using System.Windows.Forms;//TreeNode
12
13
14namespace upLibrary.upControls
15{
16 /**//// <summary>
17 /// 实现了拖放操作处理,并且每一个结点的添加和移除都能引发事件的TreeView。
18 /// </summary>
19
20 public class upTreeViewBase : System.Windows.Forms.TreeView
21 {
22 private System.ComponentModel.Container components = null;
23 private TreeNode _DragNode;
24 private bool _MoveNode = false;
25 private bool _CopyNode = false;
26 //private bool _CanDropDrag = false;
27
28 /**//// <summary>
29 /// 删除节点事件句柄(sender 是父结点或为空,e.Node是子结点)
30 /// </summary>
31
32 public delegate void NodeDeleteHandler(object Sender, upLibrary.upControls.TreeNodeEventArgs e);
33
34 /**//// <summary>
35 /// 增加节点事件句柄(sender 是父结点或为空,e.Node是子结点)
36 /// </summary>
37
38 public delegate void NodeAddHandler(object Sender, upLibrary.upControls.TreeNodeEventArgs e);
39
40 /**//// <summary>
41 /// 在删除或增加节点之间浏览子节点事件句柄(sender 是父结点或为空,e.Node是子结点)
42 /// </summary>
43
44 public delegate void BrowseTreeNodesEventHandler(object Sender, TreeNodeEventArgs e);
45
46 /**//// <summary>
47 /// 在拖放操作中改变父结点事件句柄(sender 是父结点或为空,e.Node是子结点)
48 /// </summary>
49
50 public delegate void ParentChangByDrapDropHandler(object Sender, TreeNodeEventArgs e);
51
52 控件事件声明#region 控件事件声明
53
54 [Description("在拖放操作中改变结点的父之前发生此事件")]
55
56 public event ParentChangByDrapDropHandler ParentChangingByDrapDrop;
57
58 [Description("在拖放操作中改变了结点的父之后发生此事件")]
59
60 public event ParentChangByDrapDropHandler ParentChangedByDrapDrop;
61
62 [Description("sender所代表的节点将被移除,通常在移动拖放操作之前后发生,或树已加载后再移除之前发生")]
63
64 public event NodeDeleteHandler NodeDeleting;
65
66 [Description("sender所代表的节点将被添加,通常在移动或复制拖放操作完成后发生,或树已加载后再新增之前发生")]
67
68 public event NodeAddHandler NodeAdding;
69
70 [Description("sender所代表的节点被移除,通常在移动拖放操作完成后发生,或树已加载后再移除节点后发生")]
71
72 public event NodeDeleteHandler NodeDeleted;
73
74 [Description("sender所代表的节点被添加,通常在移动或复制拖放操作完成后发生,或树已加载后再新增节点后发生")]
75
76 public event NodeAddHandler NodeAdded;
77
78 [Description("当调用BrowseNodes时从最低层开始遍历到指定node时发生此事件")]
79
80 public event BrowseTreeNodesEventHandler InverseBrowseTreeNodes;
81
82 [Description("向下遍历到指定node时发生此事件")]
83
84 public event BrowseTreeNodesEventHandler DownBrowseTreeNodes;
85
86 #endregion
87
88 public upTreeViewBase()
89 {
90 InitializeComponent();
91 }
92
93 组件设计器生成的代码#region 组件设计器生成的代码
94
95 /**//// <summary>
96 /// 设计器支持所需的方法 - 不要使用代码编辑器修改
97 /// 此方法的内容。
98 /// </summary>
99
100 private void InitializeComponent()
101 {
102 components = new System.ComponentModel.Container();
103 }
104
105 #endregion
106
107 "拖放相关"#region "拖放相关"
108
109 /**//// <summary>
110 /// 是否移动型拖放
111 /// </summary>
112
113 public bool CanMoveNode
114 {
115 get { return _MoveNode; }
116 set
117 {
118 this.ItemDrag -= new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);
119 this.DragEnter -= new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);
120 this.DragDrop -= new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);
121 _MoveNode = value;
122 if (_MoveNode)
123 {
124 this.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);
125 this.DragEnter += new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);
126 this.DragDrop += new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);
127 }
128 }
129 }
130
131 /**//// <summary>
132 /// 是否复制型拖放
133 /// </summary>
134
135 public bool CanCopyNode
136 {
137 get { return _CopyNode; }
138 set
139 {
140 this.ItemDrag -= new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);
141 this.DragEnter -= new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);
142 this.DragDrop -= new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);
143 _CopyNode = value;
144 if (_CopyNode)
145 {
146 this.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);
147 this.DragEnter += new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);
148 this.DragDrop += new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);
149 }
150 }
151 }
152
153 /**//// <summary>
154 /// 开始拖放
155 /// </summary>
156 /// <param name="sender"></param>
157 /// <param name="e"></param>
158
159 protected void TreeView_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
160 {
161 this._DragNode = (TreeNode)e.Item;
162 string strItem = e.Item.ToString();
163 if (_CopyNode && _MoveNode)
164 DoDragDrop(strItem, DragDropEffects.Move | DragDropEffects.Copy);
165 else if (_CopyNode)
166 DoDragDrop(strItem, DragDropEffects.Copy);
167 else if (_MoveNode)
168 DoDragDrop(strItem, DragDropEffects.Move);
169 }
170
171 /**//// <summary>
172 /// 拖入到控件边界内时
173 /// </summary>
174 /// <param name="sender"></param>
175 /// <param name="e"></param>
176
177 protected void TreeView_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
178 {
179 if (e.Data.GetDataPresent(DataFormats.Text))
180 {
181 if ((e.KeyState & 4) == 4 && (e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
182 e.Effect = DragDropEffects.Move; // SHIFT KeyState for move.
183 else if ((e.KeyState & 8) == 8 && (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)
184 e.Effect = DragDropEffects.Copy; // CTRL KeyState for copy.
185 else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)
186 e.Effect = DragDropEffects.Move; // By default, the drop action should be move, if allowed.
187 else
188 e.Effect = DragDropEffects.None;
189 }
190 else
191 e.Effect = DragDropEffects.None;
192 }
193
194 /**//// <summary>
195 /// 拖放完成
196 /// </summary>
197 /// <param name="sender"></param>
198 /// <param name="e"></param>
199
200 protected void TreeView_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
201 {
202 upLibrary.upControls.TreeNodeEventArgs args = null;
203 bool cancel = false;
204 Point Position = new Point(e.X, e.Y);
205 Position = this.PointToClient(Position);
206 TreeNode DropNode = this.GetNodeAt(Position); //承载结点
207 if (_DragNode.Parent == DropNode) return; //没有变嘛
208 TreeNode oldparent = _DragNode.Parent;
209
210 if ((e.Effect & DragDropEffects.Move) == DragDropEffects.Move) //如果是移动型就只是改一下父结点
211 {
212 if (ParentChangingByDrapDrop != null)
213 {
214 args = new upLibrary.upControls.TreeNodeEventArgs(_DragNode, oldparent, DropNode, TreeNodeOperateType.Modify, ref cancel);
215 ParentChangingByDrapDrop(this, args);
216 if (args.Cancel == true) return;
217 }
218 _DragNode.Remove();
219
220 if (DropNode != null)
221 DropNode.Nodes.Add(_DragNode); //如果树节点位于根级别,Parent 属性即为空引用
222 else
223 this.Nodes.Add(_DragNode);
224
225 if (ParentChangedByDrapDrop != null)
226 {
227 args = new upLibrary.upControls.TreeNodeEventArgs(_DragNode, oldparent, DropNode, TreeNodeOperateType.Modify, ref cancel);
228 ParentChangedByDrapDrop(this, args);
229 }
230 }
231 else //否则是复制型的话则要在承载结点处新增结点
232 {
233 TreeNode tNode = (TreeNode)_DragNode.Clone(); //是复制型的当然要新做一个啦,复制的部分包括克隆的树节点及其以下的树结构
234 this.AddNode(DropNode, tNode); //tNode及其子node都会在事件中去加入
235 }
236 }
237
238 #endregion
239
240 "增加和移除Node并引发事件"#region "增加和移除Node并引发事件"
241
242 /**//// <summary>
243 /// 加一个新Node至指定的上级Node
244 /// </summary>
245 /// <param name="newParent"></param>
246 /// <param name="nodeText"></param>
247 /// <returns>表示成功与否</returns>
248
249 public bool AddNode(TreeNode newParent, string nodeText)
250 {
251 return AddNode(newParent, new TreeNode(nodeText));
252 }
253
254 /**//// <summary>
255 /// 加一个Node至指定的上级Node
256 /// </summary>
257 /// <param name="newParent"></param>
258 /// <param name="node"></param>
259 /// <returns>表示成功与否</returns>
260
261 public bool AddNode(TreeNode newParent,TreeNode node)
262 {
263 bool cancel = false;
264 if (node != null)
265 {
266 this.DownBrowseTreeNodes += new BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByAdd);
267 TreeNodeEventArgs args = new TreeNodeEventArgs(node, node.Parent, newParent, TreeNodeOperateType.AddNew, ref cancel);
268 this.OnAdownBrowseTreeNodes(args); //让在事件中去一级级地处理
269 this.DownBrowseTreeNodes -= new BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByAdd);
270 }
271 return !cancel;
272 }
273
274 private void upTreeViewBase_BrowseTreeNodesByAdd(object Sender, TreeNodeEventArgs e)
275 {
276 if (e.OperateType == TreeNodeOperateType.AddNew)
277 {
278 if (this.NodeAdding != null)
279 {
280 NodeAdding(this, e);
281 if (e.Cancel) return;
282 }
283 e.Node.Remove();
284 if (e.NewParent != null)
285 e.NewParent.Nodes.Add(e.Node);
286 else
287 this.Nodes.Add(e.Node);
288 if (this.NodeAdded != null)
289 NodeAdded(this, e);
290 }
291 }
292
293 /**//// <summary>
294 /// 删除用户选定的当前Node
295 /// </summary>
296 /// <returns>表示成功与否</returns>
297
298 public bool DeleteNode()
299 {
300 TreeNode node = this.SelectedNode;
301 if (node != null)
302 {
303 return DeleteNode(node);
304 }
305 return false;
306 }
307
308 /**//// <summary>
309 /// 删除参数指定的Node及其子Node,从最低层开始,并在删除Node之前后分别引发事件NodeDeleting 和 NodeDeleted
310 /// </summary>
311 /// <param name="node"></param>
312 /// <returns>表示成功与否</returns>
313
314 public bool DeleteNode(TreeNode node)
315 {
316 bool cancel = false;
317 if (node != null)
318 {
319 this.InverseBrowseTreeNodes += new BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByDelete);
320 TreeNodeEventArgs args = new TreeNodeEventArgs(node, node.Parent, null, TreeNodeOperateType.Delete, ref cancel);
321 this.OnInverseBrowseTreeNodes(args); //让在事件中去一级级地处理
322 this.InverseBrowseTreeNodes -= new BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByDelete);
323 }
324 return !cancel;
325 }
326
327 private void upTreeViewBase_BrowseTreeNodesByDelete(object Sender, TreeNodeEventArgs e)
328 {
329 if (e.OperateType == TreeNodeOperateType.Delete)
330 {
331 if (this.NodeDeleting != null)
332 {
333 NodeDeleting(this, e);
334 if (e.Cancel) return;
335 }
336 e.Node.Remove();
337 if (this.NodeDeleted != null)
338 NodeDeleted(this, e);
339 }
340 }
341
342 #endregion
343
344 遍历并引发事件#region 遍历并引发事件
345
346 /**//// <summary>
347 /// 逆向遍历参数NODEX代表的节点及其所有子节点,从最底层起一层一层地引发BrowseChildNode事件
348 /// </summary>
349
350 protected void OnInverseBrowseTreeNodes(TreeNodeEventArgs args)
351 {
352 bool cancel = false;
353 TreeNode ChildNode = null, BrotherNode = null;
354 TreeNode Nodex = args.Node;
355 if (Nodex == null) return;
356
357 if (Nodex.Nodes.Count > 0)
358 {
359 ChildNode = Nodex.Nodes[0]; //能执行到此,表示有子节点
360 while (ChildNode != null && !args.Cancel) //兄弟节点可能有多个
361 {
362 BrotherNode = ChildNode.NextNode;
363 TreeNodeEventArgs arg = new TreeNodeEventArgs(ChildNode, ChildNode.Parent, ChildNode.Parent, args.OperateType, ref cancel);
364 OnInverseBrowseTreeNodes(arg);
365 args.Cancel = arg.Cancel;
366 if (arg.Cancel) return;
367 ChildNode = BrotherNode;
368 }
369 }
370
371 if (!args.Cancel) //如果下一级的事件中指定了取消,就不引发本级的事件了
372 {
373 if (InverseBrowseTreeNodes != null)
374 InverseBrowseTreeNodes(this, args); //当没有子节点时,该节点就是末节,在事件中去处理吧,
375 }
376 }
377
378 /**//// <summary>
379 /// 正向遍历参数NODEX代表的节点及其所有子节点,在事件中的操作不可逆,Cancel为真只能停止遍历
380 /// </summary>
381
382 protected void OnAdownBrowseTreeNodes(TreeNodeEventArgs args)
383 {
384 bool cancel = false;
385 TreeNode ChildNode = null, BrotherNode = null;
386 TreeNode Nodex = args.Node;
387
388 if (Nodex != null)
389 {
390 if (DownBrowseTreeNodes != null)
391 DownBrowseTreeNodes(this, args); //首先处理自己
392 if (args.Cancel) return; //要求取消,不用管下一级了
393 if (Nodex.Nodes.Count <= 0) return; //根本就没有下一级了
394
395 ChildNode = Nodex.Nodes[0]; //能执行到此,表示有子节点
396 while (ChildNode != null && !args.Cancel) //兄弟节点可能有多个
397 {
398 BrotherNode = ChildNode.NextNode;
399 TreeNodeEventArgs arg = new TreeNodeEventArgs(ChildNode, ChildNode.Parent, ChildNode.Parent, args.OperateType, ref cancel);
400 OnAdownBrowseTreeNodes(arg);
401 args.Cancel = arg.Cancel;
402 if (arg.Cancel) return;
403 ChildNode = BrotherNode;
404 }
405 }
406 }
407
408 #endregion
409 }
410
411 /**//// <summary>
412 /// 遍历指定的node及其子node时的操作类型
413 /// </summary>
414
415 public enum TreeNodeOperateType
416 {
417 BrowseOnly = 1, AddNew, Modify, Delete
418 }
419
420 public class TreeNodeEventArgs : System.EventArgs
421 {
422 private TreeNode _Node, _OldParent, _NewParent;
423 private bool _Cancel;
424 private TreeNodeOperateType _OperateType;
425
426 /**//// <summary>
427 /// 使用此事件数据时,Sender 应是Node的Parent
428 /// </summary>
429 /// <param name="Node">要加入到Sender所代表的Nodes的Node</param>
430 /// <param name="OperateType">发起遍历的操作类型</param>
431 /// <param name="Cancel">在事件处理中是否要求出污</param>
432
433 public TreeNodeEventArgs(TreeNode Node, TreeNode oldParent, TreeNode newParent, TreeNodeOperateType OperateType, ref bool Cancel)
434 : base()
435 {
436
437 _OldParent = oldParent;
438
439 _NewParent = newParent;
440
441 _Node = Node;
442
443 _Cancel = Cancel;
444
445 _OperateType = OperateType;
446
447 }
448
449 public TreeNode OldParent
450 {
451
452 get { return _OldParent; }
453
454 set { _OldParent = value; }
455
456 }
457
458 public TreeNode NewParent
459 {
460
461 get { return _NewParent; }
462
463 set { _NewParent = value; }
464
465 }
466
467 public TreeNode Node
468 {
469
470 get { return _Node; }
471
472 set { _Node = value; }
473
474 }
475
476 public TreeNodeOperateType OperateType
477 {
478
479 get { return _OperateType; }
480
481 set { _OperateType = value; }
482
483 }
484
485 public bool Cancel
486 {
487
488 get
489 {
490
491 return _Cancel;
492
493 }
494
495 set
496 {
497
498 _Cancel = value;
499
500 }
501
502 }
503
504 }
505
506}
507
宠辱不惊,闲看庭前花开花落;去留无意,漫随天外云卷云舒。