【问题标题】:C# WinForms - DragDrop within the same TreeViewControlC# WinForms - 在同一 TreeViewControl 中拖放
【发布时间】:2014-01-21 19:23:54
【问题描述】:

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

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

这是我当前的代码,当我运行它时,我可以看到项目已开始拖动,但窗口图标不允许将其拖放到控件上的任何节点。

我当前的代码

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();
    }
}

【问题讨论】:

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


    【解决方案1】:

    只需将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();
        }
    }
    

    【讨论】:

    • 我知道@Francesco B. 正在解决这个人的特定问题,但我想我会添加,在函数顶部插入以下行“TreeView treeView1 = (TreeView) sender;”它变成更可重复使用。
    • 请注意,如果您已经创建了自己的 TreeNode 类,则必须在调用 e.Data.GetData 时使用该类型名称,否则 draggedNode 将变为 null。
    【解决方案2】:

    在树控件上设置AllowDrop=true

    【讨论】:

    • 必须修复我的回复,我确实忘记设置 AllowDrop 但它仍然无法正常工作:( - 我正在做一些调整,可能很快会更新我的帖子
    【解决方案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();
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      对 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);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-19
        • 2010-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多