C#WinForms - DragDrop在同一个TreeViewControl中

时间:2014-01-04 00:35:15

标签: c# winforms drag-and-drop treeview

我正在尝试在同一控件中实现treeview项的DragDrop。

我希望能够将一个项目从一个节点移动到另一个节点。

这是我当前的代码,当我运行这个时,我可以看到该项目已经开始拖动,但是windows图标不允许它被删除到Control上的任何节点。

我当前的代码

private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
{
    DoDragDrop(e.Item, DragDropEffects.Move);
}

private void treeView1_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Move;
}

private void treeView1_DragDrop(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(typeof(TreeNode)))
    {
        TreeNode sourceNode = e.Data.GetData(typeof(TreeView)) as TreeNode;

        var item = new TreeNode(sourceNode.Text);


        System.Drawing.Point pt = ((TreeView)sender).PointToClient(new System.Drawing.Point(e.X, e.Y));
        TreeNode DestinationNode = ((TreeView)sender).GetNodeAt(pt);

        DestinationNode.Nodes.Add(item);
        DestinationNode.Expand();
    }
}

4 个答案:

答案 0 :(得分:22)

只需将treeView1_DragDrop功能修改为:

即可
private void treeView1_DragDrop(object sender, DragEventArgs e)
{
    // Retrieve the client coordinates of the drop location.
    Point targetPoint = treeView1.PointToClient(new Point(e.X, e.Y));

    // Retrieve the node at the drop location.
    TreeNode targetNode = treeView1.GetNodeAt(targetPoint);

    // Retrieve the node that was dragged.
    TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));

    // Confirm that the node at the drop location is not 
    // the dragged node and that target node isn't null
    // (for example if you drag outside the control)
    if (!draggedNode.Equals(targetNode) && targetNode != null)
    {
        // Remove the node from its current 
        // location and add it to the node at the drop location.
        draggedNode.Remove();
        targetNode.Nodes.Add(draggedNode);

        // Expand the node at the location 
        // to show the dropped node.
        targetNode.Expand();
    }
}

答案 1 :(得分:15)

在树形控件上设置AllowDrop=true

答案 2 :(得分:3)

稍微改进的版本,阻止您将节点放到自身或其任何后代上

private void treeView1_DragDrop(object sender, DragEventArgs e)
{
    TreeNode draggedNode = (MatfloNode)drgevent.Data.GetData(typeof(TreeNode));

    Point pt = this.PointToClient(new System.Drawing.Point(drgevent.X, drgevent.Y));
    TreeNode targetNode = this.GetNodeAt(pt);

    TreeNode parentNode = targetNode;

    if (draggedNode != null &&
        targetNode != null  )
    {
        bool canDrop = true;
        while (canDrop && (parentNode != null))
        {
            canDrop = !Object.ReferenceEquals(draggedNode, parentNode);
            parentNode = parentNode.Parent;
        }

        if (canDrop)
        {
            draggedNode.Remove();
            targetNode.Nodes.Add(draggedNode);
            targetNode.Expand();
        }
    }
}

答案 3 :(得分:3)

DragDrop处理程序的一些改进和补充,以与所有其他修订一起使用。

添加了支持:

  • 支持将节点拖放到树视图背景(底部)。节点被添加到树的底部。
  • 注意不要放弃子节点"例如,通过mrpurple并修饰它,使其与原始示例内联。
  • 也使得拖动的节点在被删除后被选中。建议在此处加载已删除节点的内容 用户可能会对当前显示的内容与选择的节点感到困惑。

注意:确保树视图控件上的AllowDrop = true,否则您无法删除节点。

private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
{
    DoDragDrop(e.Item, DragDropEffects.Move);
}

private void treeView1_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.Move;
}

private void treeView1_DragDrop(object sender, DragEventArgs e)
{
    // Retrieve the client coordinates of the drop location.
    Point targetPoint = treeView1.PointToClient(new Point(e.X, e.Y));

    // Retrieve the node at the drop location.
    TreeNode targetNode = treeView1.GetNodeAt(targetPoint);

    // Retrieve the node that was dragged.
    TreeNode draggedNode = e.Data.GetData(typeof(TreeNode));

    // Sanity check
    if (draggedNode == null)
    {
        return;
    }

    // Did the user drop on a valid target node?
    if (targetNode == null)
    {
        // The user dropped the node on the treeview control instead
        // of another node so lets place the node at the bottom of the tree.
        draggedNode.Remove();
        treeView1.Nodes.Add(draggedNode);
        draggedNode.Expand();
    }
    else
    {
        TreeNode parentNode = targetNode;

        // Confirm that the node at the drop location is not 
        // the dragged node and that target node isn't null
        // (for example if you drag outside the control)
        if (!draggedNode.Equals(targetNode) && targetNode != null)
        {
            bool canDrop = true;

            // Crawl our way up from the node we dropped on to find out if
            // if the target node is our parent. 
            while (canDrop && (parentNode != null))
            {
                canDrop = !Object.ReferenceEquals(draggedNode, parentNode);
                parentNode = parentNode.Parent;
            }

            // Is this a valid drop location?
            if (canDrop)
            {
                // Yes. Move the node, expand it, and select it.
                draggedNode.Remove();
                targetNode.Nodes.Add(draggedNode);
                targetNode.Expand();
            }
        }
    }

    // Optional: Select the dropped node and navigate (however you do it)
    treeView1.SelectedNode = draggedNode;
    // NavigateToContent(draggedNode.Tag);
}