【原创】TreeView控件实现拖拉、添加以及删除结点操作类库

ContractedBlock.gif ExpandedBlockStart.gif 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
 15ExpandedBlockStart.gifContractedBlock.gif{
 16ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 17    ///  实现了拖放操作处理,并且每一个结点的添加和移除都能引发事件的TreeView。
 18    /// </summary>

 19
 20    public class upTreeViewBase : System.Windows.Forms.TreeView
 21ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 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
 28ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 29        /// 删除节点事件句柄(sender 是父结点或为空,e.Node是子结点)
 30        /// </summary>

 31
 32        public delegate void NodeDeleteHandler(object Sender, upLibrary.upControls.TreeNodeEventArgs e);
 33
 34ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 35        /// 增加节点事件句柄(sender 是父结点或为空,e.Node是子结点)
 36        /// </summary>

 37
 38        public delegate void NodeAddHandler(object Sender, upLibrary.upControls.TreeNodeEventArgs e);
 39
 40ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 41        /// 在删除或增加节点之间浏览子节点事件句柄(sender 是父结点或为空,e.Node是子结点)
 42        /// </summary>

 43
 44        public delegate void BrowseTreeNodesEventHandler(object Sender, TreeNodeEventArgs e);
 45
 46ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 47        /// 在拖放操作中改变父结点事件句柄(sender 是父结点或为空,e.Node是子结点)
 48        /// </summary>

 49
 50        public delegate void ParentChangByDrapDropHandler(object Sender, TreeNodeEventArgs e);
 51
 52ContractedSubBlock.gifExpandedSubBlockStart.gif        控件事件声明#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()
 89ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 90            InitializeComponent();
 91        }

 92
 93ContractedSubBlock.gifExpandedSubBlockStart.gif        组件设计器生成的代码#region 组件设计器生成的代码
 94
 95ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
 96        /// 设计器支持所需的方法 - 不要使用代码编辑器修改
 97        /// 此方法的内容。
 98        /// </summary>

 99
100        private void InitializeComponent()
101ExpandedSubBlockStart.gifContractedSubBlock.gif        {
102            components = new System.ComponentModel.Container();
103        }

104
105        #endregion

106
107ContractedSubBlock.gifExpandedSubBlockStart.gif        "拖放相关"#region "拖放相关"
108
109ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
110        /// 是否移动型拖放
111        /// </summary>

112
113        public bool CanMoveNode
114ExpandedSubBlockStart.gifContractedSubBlock.gif        {
115ExpandedSubBlockStart.gifContractedSubBlock.gif            get return _MoveNode; }
116            set
117ExpandedSubBlockStart.gifContractedSubBlock.gif            {
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)
123ExpandedSubBlockStart.gifContractedSubBlock.gif                {
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
131ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
132        /// 是否复制型拖放
133        /// </summary>

134
135        public bool CanCopyNode
136ExpandedSubBlockStart.gifContractedSubBlock.gif        {
137ExpandedSubBlockStart.gifContractedSubBlock.gif            get return _CopyNode; }
138            set
139ExpandedSubBlockStart.gifContractedSubBlock.gif            {
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)
145ExpandedSubBlockStart.gifContractedSubBlock.gif                {
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
153ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <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)
160ExpandedSubBlockStart.gifContractedSubBlock.gif        {
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
171ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <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)
178ExpandedSubBlockStart.gifContractedSubBlock.gif        {
179            if (e.Data.GetDataPresent(DataFormats.Text))
180ExpandedSubBlockStart.gifContractedSubBlock.gif            {
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
194ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <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)
201ExpandedSubBlockStart.gifContractedSubBlock.gif        {
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) //如果是移动型就只是改一下父结点
211ExpandedSubBlockStart.gifContractedSubBlock.gif            {
212                if (ParentChangingByDrapDrop != null)
213ExpandedSubBlockStart.gifContractedSubBlock.gif                {
214                    args = new upLibrary.upControls.TreeNodeEventArgs(_DragNode, oldparent, DropNode, TreeNodeOperateType.Modify, ref cancel);
215                    ParentChangingByDrapDrop(this, args);
216                    if (args.Cancel == truereturn;
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)
226ExpandedSubBlockStart.gifContractedSubBlock.gif                {
227                    args = new upLibrary.upControls.TreeNodeEventArgs(_DragNode, oldparent, DropNode, TreeNodeOperateType.Modify, ref cancel);
228                    ParentChangedByDrapDrop(this, args);
229                }

230            }

231            else                          //否则是复制型的话则要在承载结点处新增结点
232ExpandedSubBlockStart.gifContractedSubBlock.gif            {
233                TreeNode tNode = (TreeNode)_DragNode.Clone();    //是复制型的当然要新做一个啦,复制的部分包括克隆的树节点及其以下的树结构
234                this.AddNode(DropNode, tNode);            //tNode及其子node都会在事件中去加入
235            }

236        }

237
238        #endregion

239
240ContractedSubBlock.gifExpandedSubBlockStart.gif        "增加和移除Node并引发事件"#region "增加和移除Node并引发事件"
241
242ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <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)
250ExpandedSubBlockStart.gifContractedSubBlock.gif        {
251            return AddNode(newParent, new TreeNode(nodeText));
252        }

253
254ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <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)
262ExpandedSubBlockStart.gifContractedSubBlock.gif        {
263            bool cancel = false;
264            if (node != null)
265ExpandedSubBlockStart.gifContractedSubBlock.gif            {
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)
275ExpandedSubBlockStart.gifContractedSubBlock.gif        {
276            if (e.OperateType == TreeNodeOperateType.AddNew)
277ExpandedSubBlockStart.gifContractedSubBlock.gif            {
278                if (this.NodeAdding != null)
279ExpandedSubBlockStart.gifContractedSubBlock.gif                {
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
293ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
294        /// 删除用户选定的当前Node
295        /// </summary>
296        /// <returns>表示成功与否</returns>

297
298        public bool DeleteNode()
299ExpandedSubBlockStart.gifContractedSubBlock.gif        {
300            TreeNode node = this.SelectedNode;
301            if (node != null)
302ExpandedSubBlockStart.gifContractedSubBlock.gif            {
303                return DeleteNode(node);
304            }

305            return false;
306        }

307
308ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
309        /// 删除参数指定的Node及其子Node,从最低层开始,并在删除Node之前后分别引发事件NodeDeleting 和 NodeDeleted
310        /// </summary>
311        /// <param name="node"></param>
312        /// <returns>表示成功与否</returns>

313
314        public bool DeleteNode(TreeNode node)
315ExpandedSubBlockStart.gifContractedSubBlock.gif        {
316            bool cancel = false;
317            if (node != null)
318ExpandedSubBlockStart.gifContractedSubBlock.gif            {
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)
328ExpandedSubBlockStart.gifContractedSubBlock.gif        {
329            if (e.OperateType == TreeNodeOperateType.Delete)
330ExpandedSubBlockStart.gifContractedSubBlock.gif            {
331                if (this.NodeDeleting != null)
332ExpandedSubBlockStart.gifContractedSubBlock.gif                {
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
344ContractedSubBlock.gifExpandedSubBlockStart.gif        遍历并引发事件#region 遍历并引发事件
345
346ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
347        /// 逆向遍历参数NODEX代表的节点及其所有子节点,从最底层起一层一层地引发BrowseChildNode事件
348        /// </summary>

349        
350        protected void OnInverseBrowseTreeNodes(TreeNodeEventArgs args)
351ExpandedSubBlockStart.gifContractedSubBlock.gif        {
352            bool cancel = false;
353            TreeNode ChildNode = null, BrotherNode = null;
354            TreeNode Nodex = args.Node;
355            if (Nodex == nullreturn;
356
357            if (Nodex.Nodes.Count > 0)
358ExpandedSubBlockStart.gifContractedSubBlock.gif            {
359                ChildNode = Nodex.Nodes[0];                //能执行到此,表示有子节点
360                while (ChildNode != null && !args.Cancel)        //兄弟节点可能有多个
361ExpandedSubBlockStart.gifContractedSubBlock.gif                {
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)                      //如果下一级的事件中指定了取消,就不引发本级的事件了
372ExpandedSubBlockStart.gifContractedSubBlock.gif            {
373                if (InverseBrowseTreeNodes != null)
374                    InverseBrowseTreeNodes(this, args);          //当没有子节点时,该节点就是末节,在事件中去处理吧,
375            }

376        }

377
378ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
379        /// 正向遍历参数NODEX代表的节点及其所有子节点,在事件中的操作不可逆,Cancel为真只能停止遍历
380        /// </summary>

381        
382        protected void OnAdownBrowseTreeNodes(TreeNodeEventArgs args)
383ExpandedSubBlockStart.gifContractedSubBlock.gif        {
384            bool cancel = false;
385            TreeNode ChildNode = null, BrotherNode = null;
386            TreeNode Nodex = args.Node;
387
388            if (Nodex != null)
389ExpandedSubBlockStart.gifContractedSubBlock.gif            {
390                if (DownBrowseTreeNodes != null)
391                    DownBrowseTreeNodes(this, args);          //首先处理自己
392                if (args.Cancel) return;                //要求取消,不用管下一级了
393                if (Nodex.Nodes.Count <= 0return;            //根本就没有下一级了
394
395                ChildNode = Nodex.Nodes[0];                //能执行到此,表示有子节点
396                while (ChildNode != null && !args.Cancel)          //兄弟节点可能有多个
397ExpandedSubBlockStart.gifContractedSubBlock.gif                {
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
411ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
412    /// 遍历指定的node及其子node时的操作类型
413    /// </summary>

414
415    public enum TreeNodeOperateType
416ExpandedSubBlockStart.gifContractedSubBlock.gif    {
417        BrowseOnly = 1, AddNew, Modify, Delete
418    }

419
420    public class TreeNodeEventArgs : System.EventArgs
421ExpandedSubBlockStart.gifContractedSubBlock.gif    {
422        private TreeNode _Node, _OldParent, _NewParent;
423        private bool _Cancel;
424        private TreeNodeOperateType _OperateType;
425
426ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <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()
435ExpandedSubBlockStart.gifContractedSubBlock.gif        {
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
450ExpandedSubBlockStart.gifContractedSubBlock.gif        {
451
452ExpandedSubBlockStart.gifContractedSubBlock.gif            get return _OldParent; }
453
454ExpandedSubBlockStart.gifContractedSubBlock.gif            set { _OldParent = value; }
455
456        }

457
458        public TreeNode NewParent
459ExpandedSubBlockStart.gifContractedSubBlock.gif        {
460
461ExpandedSubBlockStart.gifContractedSubBlock.gif            get return _NewParent; }
462
463ExpandedSubBlockStart.gifContractedSubBlock.gif            set { _NewParent = value; }
464
465        }

466
467        public TreeNode Node
468ExpandedSubBlockStart.gifContractedSubBlock.gif        {
469
470ExpandedSubBlockStart.gifContractedSubBlock.gif            get return _Node; }
471
472ExpandedSubBlockStart.gifContractedSubBlock.gif            set { _Node = value; }
473
474        }

475
476        public TreeNodeOperateType OperateType
477ExpandedSubBlockStart.gifContractedSubBlock.gif        {
478
479ExpandedSubBlockStart.gifContractedSubBlock.gif            get return _OperateType; }
480
481ExpandedSubBlockStart.gifContractedSubBlock.gif            set { _OperateType = value; }
482
483        }

484
485        public bool Cancel
486ExpandedSubBlockStart.gifContractedSubBlock.gif        {
487
488            get
489ExpandedSubBlockStart.gifContractedSubBlock.gif            {
490
491                return _Cancel;
492
493            }

494
495            set
496ExpandedSubBlockStart.gifContractedSubBlock.gif            {
497
498                _Cancel = value;
499
500            }

501
502        }

503
504    }

505
506}

507

转载于:https://www.cnblogs.com/Jackey_Chen/archive/2008/10/30/1323241.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值