效果
1.添加TreeView控件
添加并设置TreeView初始值
2.功能实现
2.1 新建DragableTree类,写一个带有拖放事件的构造方法
// 可拖放Tree
internal class DragableTree
{
private TreeView tree = null;
private TreeNode nodeInDrag = null;
// 传入一个tree,添加拖放事件
internal DragableTree(TreeView tree)
{
this.tree = tree;
this.tree.AllowDrop = true;
this.tree.HideSelection = false;
this.tree.ItemDrag += TreeView_ItemDrag;
this.tree.DragDrop += (sender, e) => TreeView_DragDrop(tree, nodeInDrag, e);
this.tree.DragOver += (sender, e) => TreeView_DragOver(tree, nodeInDrag, e);
this.tree.DragLeave += (sender, e) => TreeView_Leave(nodeInDrag);
}
}
2.2 拖动事件
对应构造方法的ItemDrag、DragDrop、DragOver、DragLeave
// 拖动节点
internal void TreeView_ItemDrag(object sender, ItemDragEventArgs e)
{
nodeInDrag = (TreeNode)e.Item;
tree.DoDragDrop(e.Item, DragDropEffects.Move);
}
// 拖动经过
internal static void TreeView_DragOver(TreeView tree, TreeNode nodeInDrag, DragEventArgs e)
{
// 获取目标位置 -> 目标节点
Point pointTarget = tree.PointToClient(new Point(e.X, e.Y));
TreeNode nodeTargrt = tree.GetNodeAt(pointTarget);
tree.SelectedNode = nodeTargrt;
// 节点是否能放置
bool canDrop = true;
// 目标节点:存在、不是自身、不是自身的父节点
if (nodeTargrt != null
&& nodeTargrt != nodeInDrag
&& nodeTargrt != nodeInDrag.Parent)
{
// 目标节点的父节点:不含自身
TreeNode parentNode = nodeTargrt;
while (parentNode.Parent != null)
{
// 获取父节点
parentNode = parentNode.Parent;
// 父节点是自身,不可放置
if (parentNode == nodeInDrag)
{
canDrop = false;
break;
}
}
}
else // 不可放置
{
canDrop = false;
}
if (canDrop) // 可放置
{
e.Effect = DragDropEffects.Move;
ColorToGray(nodeInDrag);
}
else // 不可放置
{
e.Effect = DragDropEffects.None;
ColorToRad(nodeInDrag);
}
}
// 拖动放置
internal static void TreeView_DragDrop(TreeView tree, TreeNode nodeInDrag, DragEventArgs e)
{
// 获取目标位置 -> 目标节点
Point pointTarget = tree.PointToClient(new Point(e.X, e.Y));
TreeNode nodeTargrt = tree.GetNodeAt(pointTarget);
// 清除被移动的节点
if (nodeInDrag.Parent == null)
tree.Nodes.Remove(nodeInDrag);
else
nodeInDrag.Parent.Nodes.Remove(nodeInDrag);
// 添加节点,展开
nodeTargrt.Nodes.Add(nodeInDrag);
nodeTargrt.Expand();
// 恢复颜色
ColorToDefault(nodeInDrag);
}
// 拖动离开:未放置
private static void TreeView_Leave(TreeNode nodeInDrag)
{
// 恢复颜色
ColorToDefault(nodeInDrag);
}
2.3 改变颜色
被拖动:灰色
不可放置:红色
离开、放置:恢复默认
// 默认颜色
internal static void ColorToDefault(TreeNode nodeInDrag)
{
nodeInDrag.BackColor = SystemColors.Window;
nodeInDrag.ForeColor = SystemColors.ControlText;
}
// 被拖动的颜色
internal static void ColorToGray(TreeNode nodeInDrag)
{
nodeInDrag.BackColor = Color.LightGray;
nodeInDrag.ForeColor = SystemColors.ControlText;
}
// 被拖动无法放置的颜色
internal static void ColorToRad(TreeNode nodeInDrag)
{
nodeInDrag.BackColor = Color.Pink;
nodeInDrag.ForeColor = Color.Red;
}
3.添加功能到TreeView
在Form类中声明一个DragableTree,在Form方法中通过new获得拖拽功能
public partial class Form1 : Form
{
DragableTree dt;
public Form1()
{
InitializeComponent();
dt = new(treeView1);
}
}