HotTracking в TreeView не работает с Drag & Drop - PullRequest
1 голос
/ 14 сентября 2011

У меня есть простой TreeView со свойством HotTracking, установленным в True. Это работает, когда я перемещаю мышь над элементом. Но это не работает, когда я использую Drag & Drop и перетаскиваем что-то поверх элемента TreeView. Есть ли способ использовать HotTracking с DragDrop? Или какие-нибудь обходные пути?

Ответы [ 2 ]

1 голос
/ 14 сентября 2011

По умолчанию элемент управления получает только уведомления D + D, а не сообщения мыши.Вы можете просто выбрать узел самостоятельно:

    private void treeView1_DragOver(object sender, DragEventArgs e) {
        if (e.Data.GetDataPresent("something")) {
            var pos = treeView1.PointToClient(new Point(e.X, e.Y));
            var hit = treeView1.HitTest(pos);
            if (hit.Location == TreeViewHitTestLocations.Label) {
                treeView1.SelectedNode = hit.Node;
                e.Effect = DragDropEffects.Copy;
            }
            else e.Effect = DragDropEffects.None;
        }
    }

Обычно вам нужно проделать дополнительную работу, чтобы позволить пользователю прокручивать представление и расширять узлы.

0 голосов
/ 04 июля 2013

Выбор узла в соответствии с предложением @Hans - это простое решение, но оно может быть неприменимо, если при выборе узла есть какие-то события или вам просто нужно сохранить выбранный узел.Единственный способ, который я нашел, - это custumDraw узел, использующий VisualStylesRenderer.

private void plTree_DragOver(object sender, DragEventArgs e)
    {            
        Point pt = plTree.PointToClient(new Point(e.X, e.Y));

        var overNode = plTree.GetNodeAt(pt);
        bool canMoveTo = overNode != null && 
                         TreeNodeIsFolder(overNode) && 
                         !IsFirstNodeParentToSecond(GetDraggedNodes(e)[0], overNode);// all dragged nodes are of the same parent
        e.Effect = canMoveTo ? DragDropEffects.Move : DragDropEffects.None;

        if (overNode == null) return;

        if (_lastCustomDrawNode != overNode)
        {
            NormalDrawNode(_lastCustomDrawNode);
            CustomDrawNode(overNode);
        }
        _lastCustomDrawNode = overNode;
    }

    private void NormalDrawNode(TreeNode aNode)
    {
        if (aNode == null) return;

        if (_normalNodeRenderer == null)
            _normalNodeRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 1);
        Debug.WriteLine("normal render" + DateTime.Now);
        RenderTreeNode(_normalNodeRenderer, aNode, true);

        _lastCustomDrawNode = null;
    }

    private void CustomDrawNode(TreeNode aNode)
    {
        if (_hotNodeRenderer == null)
            _hotNodeRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 2);
        Debug.WriteLine("custom render" + DateTime.Now);
        RenderTreeNode(_hotNodeRenderer, aNode, false);
    }

    private void RenderTreeNode(VisualStyleRenderer renderer, TreeNode aNode, bool drawDefaultBck)
    {
        if(_treeGraphics == null)
             _treeGraphics = plTree.CreateGraphics();

        const int iconShift = 21;
        Rectangle aRec = aNode.Bounds;

        var bckRec = new Rectangle(aRec.Location.X - iconShift, aRec.Location.Y, aRec.Width + iconShift, aRec.Height);

        if (!drawDefaultBck)
            renderer.DrawBackground(_treeGraphics, bckRec);
        else
            _treeGraphics.FillRectangle(_treebckgBrush, bckRec);

        var textRec = new Rectangle(aRec.Location.X + 1, aRec.Location.Y - 1, aRec.Width, aRec.Height);
        TextRenderer.DrawText(_treeGraphics, aNode.Text, GetTreeNodeFont(aNode), textRec, Color.FromKnownColor(KnownColor.ControlText));

        var imgRec = new Rectangle(aRec.Location.X + 2 - iconShift, aRec.Location.Y, 16, 16);
        renderer.DrawImage(_treeGraphics, imgRec, ImageListTree.Images[aNode.ImageIndex]);
    }

Этот пост очень помогает при рисовании тем: VisualStyleRenderer и темы (WinForms)

...