web-dev-qa-db-ja.com

C#WinForms-同じTreeViewControl内のDragDrop

同じコントロール内にツリービューアイテムの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();
    }
}
14
IEnumerable

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

セットする AllowDrop=trueツリーコントロール上。

16
Gary

ノードをそれ自体にドロップしないようにするわずかに改善されたバージョンまたはその子孫のいずれか

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
mrpurple

他のすべてのリビジョンに合わせて、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);
}
3
GrayDwarf