分享
 
 
 

实现了拖放操作处理,并且每一个结点的添加和移除都能引发事件的TreeView

王朝c#·作者佚名  2006-12-17
窄屏简体版  字體: |||超大  

///如未特别说明,本人所发表的技术文章都为原创, 任何人引用都请注明出处,并包含本声明

///作者: CSDN网名alias88,邮件:alias88@163.com,QQ:63343

using System;

using System.ComponentModel;

using System.Collections;

using System.Diagnostics;

using System.Drawing;

using System.Windows.Forms;

using System.Data;

namespace upLibrary.upControls

{

/// <summary>

/// 实现了拖放操作处理,并且每一个结点的添加和移除都能引发事件的TreeView。

/// </summary>

public class upTreeViewBase : System.Windows.Forms.TreeView

{

private System.ComponentModel.Container components = null;

private TreeNode _DragNode;

private bool _MoveNode=false;

private bool _CopyNode=false;

private bool _CanDropDrag=false;

/// <summary>

/// 删除节点事件句柄(sender 是父结点或为空,e.Node是子结点)

/// </summary>

public delegate void NodeDeleteHandler (object Sender,upLibrary.upControls.TreeNodeEventArgs e);

/// <summary>

/// 增加节点事件句柄(sender 是父结点或为空,e.Node是子结点)

/// </summary>

public delegate void NodeAddHandler (object Sender,upLibrary.upControls.TreeNodeEventArgs e);

/// <summary>

/// 在删除或增加节点之间浏览子节点事件句柄(sender 是父结点或为空,e.Node是子结点)

/// </summary>

public delegate void

BrowseTreeNodesEventHandler (object Sender,TreeNodeEventArgs e);

/// <summary>

/// 在拖放操作中改变父结点事件句柄(sender 是父结点或为空,e.Node是子结点)

/// </summary>

public delegate void ParentChangByDrapDropHandler (object Sender,TreeNodeEventArgs e);

[Description("在拖放操作中改变结点的父之前发生此事件") ]

public event ParentChangByDrapDropHandler ParentChangingByDrapDrop;

[Description("在拖放操作中改变了结点的父之后发生此事件") ]

public event ParentChangByDrapDropHandler ParentChangedByDrapDrop;

[Description("sender所代表的节点将被移除,通常在移动拖放操作之前后发生,或树已加载后再移除之前发生") ]

public event NodeDeleteHandler NodeDeleting;

[Description("sender所代表的节点将被添加,通常在移动或复制拖放操作完成后发生,或树已加载后再新增之前发生") ]

public event NodeAddHandler NodeAdding;

[Description("sender所代表的节点被移除,通常在移动拖放操作完成后发生,或树已加载后再移除节点后发生") ]

public event NodeDeleteHandler NodeDeleted;

[Description("sender所代表的节点被添加,通常在移动或复制拖放操作完成后发生,或树已加载后再新增节点后发生") ]

public event NodeAddHandler NodeAdded;

[Description("当调用BrowseNodes时从最低层开始遍历到指定node时发生此事件") ]

public event

BrowseTreeNodesEventHandler InverseBrowseTreeNodes;

[Description("向下遍历到指定node时发生此事件") ]

public event

BrowseTreeNodesEventHandler DownBrowseTreeNodes;

public upTreeViewBase()

{

InitializeComponent();

}

/// <summary>

/// 清理所有正在使用的资源。

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if(components != null)

{

components.Dispose();

}

}

base.Dispose( disposing );

}

#region 组件设计器生成的代码

/// <summary>

/// 设计器支持所需的方法 - 不要使用代码编辑器修改

/// 此方法的内容。

/// </summary>

private void InitializeComponent()

{

components = new System.ComponentModel.Container();

}

#endregion

#region "拖放相关"

/// <summary>

/// 是否移动型拖放

/// </summary>

public bool CanMoveNode

{

get{return _MoveNode;}

set

{

this.ItemDrag -= new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);

this.DragEnter -= new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);

this.DragDrop -= new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);

_MoveNode=value;

if (_MoveNode)

{

this.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);

this.DragEnter += new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);

this.DragDrop += new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);

}

}

}

/// <summary>

/// 是否复制型拖放

/// </summary>

public bool CanCopyNode

{

get{return _CopyNode;}

set

{

this.ItemDrag -= new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);

this.DragEnter -= new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);

this.DragDrop -= new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);

_CopyNode=value;

if (_CopyNode)

{

this.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(TreeView_ItemDrag);

this.DragEnter += new System.Windows.Forms.DragEventHandler(TreeView_DragEnter);

this.DragDrop += new System.Windows.Forms.DragEventHandler(TreeView_DragDrop);

}

}

}

/// <summary>

/// 开始拖放

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void TreeView_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)

{

this._DragNode = (TreeNode)e.Item;

string strItem = e.Item.ToString();

if (_CopyNode && _MoveNode)

DoDragDrop(strItem, DragDropEffects.Move | DragDropEffects.Copy );

else if (_CopyNode)

DoDragDrop(strItem, DragDropEffects.Copy );

else if (_MoveNode)

DoDragDrop(strItem, DragDropEffects.Move );

}

/// <summary>

/// 拖入到控件边界内时

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void TreeView_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)

{

if (e.Data.GetDataPresent(DataFormats.Text))

{

if ((e.KeyState & 4) == 4 && (e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)

e.Effect = DragDropEffects.Move; // SHIFT KeyState for move.

else if ((e.KeyState & 8) == 8 && (e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)

e.Effect = DragDropEffects.Copy; // CTRL KeyState for copy.

else if ((e.AllowedEffect & DragDropEffects.Move) == DragDropEffects.Move)

e.Effect = DragDropEffects.Move; // By default, the drop action should be move, if allowed.

else

e.Effect = DragDropEffects.None;

}

else

e.Effect = DragDropEffects.None;

}

/// <summary>

/// 拖放完成

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void TreeView_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)

{

upLibrary.upControls.TreeNodeEventArgs args=null;

bool cancel=false;

Point Position = new Point(e.X ,e.Y );

Position = this.PointToClient(Position);

TreeNode DropNode = this.GetNodeAt(Position); //承载结点

if (_DragNode.Parent == DropNode) return ; //没有变嘛

TreeNode oldparent=_DragNode.Parent ;

if ((e.Effect & DragDropEffects.Move) ==DragDropEffects.Move ) //如果是移动型就只是改一下父结点

{

if (ParentChangingByDrapDrop !=null)

{

args=new upLibrary.upControls.TreeNodeEventArgs(_DragNode,oldparent ,DropNode,TreeNodeOperateType.Modify ,ref cancel);

ParentChangingByDrapDrop(this ,args);

if (args.Cancel ==true) return ;

}

_DragNode.Remove();

if (DropNode!=null)

DropNode.Nodes .Add (_DragNode); //如果树节点位于根级别,Parent 属性即为空引用

else

this.Nodes.Add (_DragNode);

if (ParentChangedByDrapDrop!=null)

{

args=new upLibrary.upControls.TreeNodeEventArgs(_DragNode,oldparent ,DropNode,TreeNodeOperateType.Modify ,ref cancel);

ParentChangedByDrapDrop(this,args);

}

}

else //否则是复制型的话则要在承载结点处新增结点

{

TreeNode tNode=(TreeNode)_DragNode.Clone (); //是复制型的当然要新做一个啦,复制的部分包括克隆的树节点及其以下的树结构

this.AddNode (DropNode,tNode); //tNode及其子node都会在事件中去加入

}

}

#endregion

#region "增加和移除Node并引发事件"

/// <summary>

/// 加一个新Node至指定的上级Node

/// </summary>

/// <param name="newParent"></param>

/// <param name="nodeText"></param>

/// <returns>表示成功与否</returns>

public bool AddNode(TreeNode newParent,string nodeText)

{

return AddNode(newParent,new TreeNode (nodeText));

}

/// <summary>

/// 加一个Node至指定的上级Node

/// </summary>

/// <param name="newParent"></param>

/// <param name="node"></param>

/// <returns>表示成功与否</returns>

public bool AddNode(TreeNode newParent,TreeNode node)

{

bool cancel=false;

if (node!=null)

{

this.DownBrowseTreeNodes +=new

BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByAdd);

TreeNodeEventArgs args=new TreeNodeEventArgs (node,node.Parent ,newParent,TreeNodeOperateType.AddNew ,ref cancel);

this.OnAdownBrowseTreeNodes (args); //让在事件中去一级级地处理

this.DownBrowseTreeNodes -=new

BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByAdd);

}

return !cancel ;

}

private void upTreeViewBase_BrowseTreeNodesByAdd(object Sender, TreeNodeEventArgs e)

{

if (e.OperateType ==TreeNodeOperateType.AddNew )

{

if (this.NodeAdding !=null)

{

NodeAdding(this ,e);

if (e.Cancel ) return ;

}

e.Node.Remove ();

if (e.NewParent !=null)

e.NewParent.Nodes.Add (e.Node );

else

this.Nodes.Add (e.Node );

if(this.NodeAdded !=null)

NodeAdded(this ,e);

}

}

/// <summary>

/// 删除用户选定的当前Node

/// </summary>

/// <returns>表示成功与否</returns>

public bool DeleteNode()

{

TreeNode node=this.SelectedNode ;

if (node!=null)

{

return DeleteNode(node);

}

return false;

}

/// <summary>

/// 删除参数指定的Node及其子Node,从最低层开始,并在删除Node之前后分别引发事件NodeDeleting 和 NodeDeleted

/// </summary>

/// <param name="node"></param>

/// <returns>表示成功与否</returns>

public bool DeleteNode(TreeNode node)

{

bool cancel=false;

if (node!=null)

{

this.InverseBrowseTreeNodes +=new

BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByDelete);

TreeNodeEventArgs args=new TreeNodeEventArgs (node,node.Parent ,null,TreeNodeOperateType.Delete ,ref cancel);

this.OnInverseBrowseTreeNodes (args ); //让在事件中去一级级地处理

this.InverseBrowseTreeNodes -=new

BrowseTreeNodesEventHandler(upTreeViewBase_BrowseTreeNodesByDelete);

}

return !cancel ;

}

private void upTreeViewBase_BrowseTreeNodesByDelete(object Sender, TreeNodeEventArgs e)

{

if (e.OperateType ==TreeNodeOperateType.Delete )

{

if (this.NodeDeleting !=null)

{

NodeDeleting(this ,e);

if (e.Cancel ) return ;

}

e.Node.Remove ();

if(this.NodeDeleted !=null)

NodeDeleted(this ,e);

}

}

#endregion

#region 遍历并引发事件

/// <summary>

/// 逆向遍历参数NODEX代表的节点及其所有子节点,从最底层起一层一层地引发BrowseChildNode事件

/// </summary>

protected void OnInverseBrowseTreeNodes(TreeNodeEventArgs args)

{

bool cancel=false;

TreeNode ChildNode=null,BrotherNode=null;

TreeNode Nodex=args.Node ;

if (Nodex==null ) return ;

if ( Nodex.Nodes.Count >0 )

{

ChildNode=Nodex.Nodes[0] ; //能执行到此,表示有子节点

while (ChildNode!=null && !args.Cancel ) //兄弟节点可能有多个

{

BrotherNode=ChildNode.NextNode;

TreeNodeEventArgs arg=new TreeNodeEventArgs (ChildNode,ChildNode.Parent ,ChildNode.Parent ,args.OperateType ,ref cancel);

OnInverseBrowseTreeNodes(arg);

args.Cancel =arg.Cancel ;

if (arg.Cancel ) return ;

ChildNode=BrotherNode;

}

}

if (!args.Cancel ) //如果下一级的事件中指定了取消,就不引发本级的事件了

{

if(InverseBrowseTreeNodes!=null)

InverseBrowseTreeNodes (this,args); //当没有子节点时,该节点就是末节,在事件中去处理吧,

}

}

/// <summary>

/// 正向遍历参数NODEX代表的节点及其所有子节点,在事件中的操作不可逆,Cancel为真只能停止遍历

/// </summary>

protected void OnAdownBrowseTreeNodes(TreeNodeEventArgs args)

{

bool cancel=false;

TreeNode ChildNode=null,BrotherNode=null;

TreeNode Nodex =args.Node ;

if (Nodex!=null)

{

if(DownBrowseTreeNodes!=null)

DownBrowseTreeNodes (this ,args); //首先处理自己

if (args.Cancel ) return ; //要求取消,不用管下一级了

if (Nodex.Nodes.Count<=0) return ; //根本就没有下一级了

ChildNode=Nodex.Nodes[0] ; //能执行到此,表示有子节点

while (ChildNode!=null && !args.Cancel) //兄弟节点可能有多个

{

BrotherNode=ChildNode.NextNode;

TreeNodeEventArgs arg=new TreeNodeEventArgs (ChildNode,ChildNode.Parent ,ChildNode.Parent ,args.OperateType ,ref cancel);

OnAdownBrowseTreeNodes(arg);

args.Cancel =arg.Cancel ;

if (arg.Cancel ) return ;

ChildNode=BrotherNode;

}

}

}

#endregion

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// <summary>

/// 遍历指定的node及其子node时的操作类型

/// </summary>

public enum TreeNodeOperateType

{

BrowseOnly=1,AddNew,Modify,Delete

}

public class TreeNodeEventArgs:System.EventArgs

{

private TreeNode _Node,_OldParent,_NewParent;

private bool _Cancel;

private TreeNodeOperateType _OperateType;

/// <summary>

/// 使用此事件数据时,Sender 应是Node的Parent

/// </summary>

/// <param name="Node">要加入到Sender所代表的Nodes的Node</param>

/// <param name="OperateType">发起遍历的操作类型</param>

/// <param name="Cancel">在事件处理中是否要求出污</param>

public TreeNodeEventArgs(TreeNode Node ,TreeNode oldParent,TreeNode newParent,TreeNodeOperateType OperateType, ref bool Cancel ):base()

{

_OldParent=oldParent;

_NewParent=newParent;

_Node=Node;

_Cancel=Cancel;

_OperateType=OperateType;

}

public TreeNode OldParent

{

get { return _OldParent; }

set { _OldParent = value; }

}

public TreeNode NewParent

{

get { return _NewParent; }

set { _NewParent = value; }

}

public TreeNode Node

{

get { return _Node; }

set { _Node = value; }

}

public TreeNodeOperateType OperateType

{

get { return _OperateType;}

set { _OperateType=value; }

}

public bool Cancel

{

get {

return _Cancel;

}

set {

_Cancel = value;

}

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有