using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using System.Drawing; namespace DropTree ... { public abstract class BaseTree : TreeView ...{ private bool droping; private const string NODE_TYPE = "System.Windows.Forms.TreeNode"; private string nodeType; protected BaseTree() : base() ...{ AllowDrop = true; ItemDrag += new ItemDragEventHandler(BaseTree_ItemDrag); DragEnter += new DragEventHandler(BaseTree_DragEnter); DragOver += new DragEventHandler(BaseTree_DragOver); DragDrop += new DragEventHandler(BaseTree_DragDrop); AfterSelect += new System.Windows.Forms.TreeViewEventHandler(BaseTree_AfterSelect); nodeType = NODE_TYPE; } /**//// <summary> /// 如果重写树节点,请重新为此属性赋值.格式:命名空间.类名 /// </summary> public string NodeType ...{ get ...{ return nodeType; } set ...{ if (string.IsNullOrEmpty(value)) nodeType = NODE_TYPE; else nodeType = value; } } /**//// <summary> /// 选中节点后的操作 /// </summary> protected abstract void AfterSelectedNode(); /**//// <summary> /// 移动后的操作 /// </summary> /// <param name="parentNode">目标节点</param> /// <param name="dropNode">移动节点</param> protected abstract void MoveNode(TreeNode parentNode, TreeNode dropNode); /**//// <summary> /// 检查当前移动节点是否能移动到该目标节点下,移动提示对话框也可在此操作 /// </summary> /// <param name="parentNode">目标节点</param> /// <param name="dropNode">移动节点</param> /// <returns>如果允许</returns> protected abstract bool AllowMove(TreeNode parentNode, TreeNode dropNode); private void BaseTree_DragDrop(object sender, DragEventArgs e) ...{ this.droping = true; if (!e.Data.GetDataPresent(nodeType, true)) this.droping = false; else ...{ TreeNode dropNode = (TreeNode)e.Data.GetData(nodeType); TreeNode parentNode = SelectedNode; if ((e.Effect != DragDropEffects.Copy) && (parentNode != null) && AllowMove(parentNode, dropNode)) ...{ MoveNode(parentNode, dropNode); dropNode.Remove(); parentNode.Nodes.Add(dropNode); parentNode.Expand(); SelectedNode = dropNode; } this.droping = false; } } private void BaseTree_DragEnter(object sender, DragEventArgs e) ...{ if (e.Data.GetDataPresent(nodeType, true)) ...{ if (((e.KeyState & 8) == 8) & ((e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)) ...{ e.Effect = DragDropEffects.Copy; } else ...{ e.Effect = DragDropEffects.Move; } } else ...{ e.Effect = DragDropEffects.None; } } private void BaseTree_DragOver(object sender, DragEventArgs e) ...{ this.droping = true; if (!e.Data.GetDataPresent(nodeType, true)) ...{ this.droping = false; } else ...{ Point point = PointToClient(new Point(e.X, e.Y)); TreeNode targetNode = this.GetNodeAt(point); SelectedNode = targetNode; TreeNode dropNode = (TreeNode)e.Data.GetData(nodeType); if (targetNode == null) ...{ e.Effect = DragDropEffects.None; this.droping = false; } else ...{ while (targetNode != null) ...{ if (targetNode == dropNode || dropNode.Parent == SelectedNode) ...{ e.Effect = DragDropEffects.None; this.droping = false; return; } targetNode = targetNode.Parent; } if (((e.KeyState & 8) == 8) & ((e.AllowedEffect & DragDropEffects.Copy) == DragDropEffects.Copy)) ...{ e.Effect = DragDropEffects.Copy; } else ...{ e.Effect = DragDropEffects.Move; } this.droping = false; } } } private void BaseTree_ItemDrag(object sender, ItemDragEventArgs e) ...{ if (e.Button == MouseButtons.Left) ...{ this.droping = true; this.DoDragDrop(e.Item, DragDropEffects.Move); this.droping = false; } } private void BaseTree_AfterSelect(object sender, TreeViewEventArgs e) ...{ if (droping == true)//在节点拖放时,跳过选中节点后的操作 return; else AfterSelectedNode(); } } public class TestTree:BaseTree...{ public TestTree() : base() ...{ } protected override void AfterSelectedNode() ...{ MessageBox.Show(SelectedNode.Text,string.Empty, MessageBoxButtons.OK,MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, 0); } protected override void MoveNode(TreeNode parentNode, TreeNode dropNode) ...{ //throw new Exception("The method or operation is not implemented."); } protected override bool AllowMove(TreeNode parentNode, TreeNode dropNode) ...{ return true; } }}