当鼠标右键拖动时,树视图没有视觉更新

本文关键字:视图 视觉 更新 鼠标 右键 拖动 | 更新日期: 2023-09-27 17:52:54

我有一个TreeView控件,我已经实现了拖放。DragOver处理程序中有一些代码可以突出显示被拖动节点的正确目标节点,这很好地工作了。我使用鼠标左键来移动节点,使用鼠标右键来复制节点。问题是,当使用右键时,TreeView在拖动操作期间不能正确显示所选节点。正在选择适当的节点,我已经用停止点验证了这一点,但TreeView本身没有显示这一点。当使用鼠标左键时,它会显示它。

    private void DocumentMap_ItemDrag(object sender, ItemDragEventArgs e)
    {
        // Only handle TreeNode objects
        if (e.Item.GetType() != typeof(TreeNode)) return;
        this.dragNode = e.Item as TreeNode;
        var sourceType = XmlItem.FromElement(this.dragNode.Tag as XElement).ItemType;
        if (sourceType == Xml.ProjectHeader || sourceType == Xml.GroupHeader) return;
        switch (e.Button)
        {
            case System.Windows.Forms.MouseButtons.Left:
                DoDragDrop(e.Item, DragDropEffects.Move);
                break;
            case System.Windows.Forms.MouseButtons.Right:
                DoDragDrop(e.Item, DragDropEffects.Copy);
                break;
        }
        this.dragNode = null;
    }
    private void DocumentMap_DragOver(object sender, DragEventArgs e)
    {
        if (this.dragNode == null) return;
        var targetType = XmlItem.FromNode(this.dragNode.Parent).ItemType;
        var hoverNode = DocumentMap.GetNodeAt(DocumentMap.PointToClient(new Point(e.X, e.Y)));
        var targetNode = FindNodeInAncestors(hoverNode, targetType);
        if (targetNode != null && targetNode != this.dragNode.Parent)
            DocumentMap.SelectedNode = targetNode;
        else
            DocumentMap.SelectedNode = null;
    }

当鼠标右键拖动时,树视图没有视觉更新

我自己也遇到过这个问题,使用本地send消息调用来强制项目选择对我有效:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public static class NativeExtensions
{
    private const int TVM_SELECTITEM = (0x1100 + 11);
    [DllImport("user32.dll", CharSet=CharSet.Auto)]
    public static extern IntPtr SendMessage(HandleRef hWnd, int msg, IntPtr wParam, IntPtr lParam);
    /// <summary>
    /// Forces the selection of this <see cref="System.Windows.Forms.TreeNode"/> using an unsafe SendMessage call
    /// </summary>
    /// <param name="selectionType">Type of selection to make</param>
    /// <exception cref="System.NullReferenceException">This node is null</exception>
    /// <exception cref="System.ArgumentException">The handle for this node is not created, the node does
    /// not have a parent <see cref="System.Windows.Forms.TreeView"/>, or the handle for the node's parent <see cref="System.Windows.Forms.TreeView"/>
    /// is not created</exception>
    public static void ForceSelection(this TreeNode nodeToSelect, UnmanagedTreeNodeSelectType selectionType)
    {
        if (nodeToSelect == null)
            throw new NullReferenceException();
        if (nodeToSelect.Handle == IntPtr.Zero)
            throw new ArgumentException("Handle for node is not created");
        if (nodeToSelect.TreeView == null)
            throw new ArgumentException("Node does not have a parent TreeView.");
        if (nodeToSelect.TreeView.Handle == IntPtr.Zero)
            throw new ArgumentException("Handle for node's parent TreeView is not created.");
        nodeToSelect.TreeView.SelectedNode = nodeToSelect;
        SendMessage(new HandleRef(nodeToSelect.TreeView, nodeToSelect.TreeView.Handle), TVM_SELECTITEM, (IntPtr)selectionType, nodeToSelect.Handle);
    }
    /// <summary>
    /// Type of selection to make when forcing a <see cref="System.Windows.Forms.TreeNode"/> selection with unmanaged code
    /// </summary>
    public enum UnmanagedTreeNodeSelectType
    {
        //Documentation taken from http://msdn.microsoft.com/en-us/library/31917zyz.aspx
        /// <summary>
        /// Sets the selection to the given item
        /// </summary>
        SetSelection = 0x0009, //TVGN_CARET
        /// <summary>
        /// Redraws the given item in the style used to indicate the target of a drag-and-drop operation
        /// </summary>
        DragAndDropTarget = 0x0008, //TVGN_DROPHILITE
        /// <summary>
        /// Scrolls the tree view vertically so that the given item is the first visible item
        /// </summary>
        FirstVisible = 0x0005, //TVGN_FIRSTVISIBLE
    }
}

使用它:

targetNode.ForceSelection(NativeExtensions.UnmanagedTreeNodeSelectType.DragAndDropTarget);