右键拖动时TreeView无法直观更新

时间:2014-03-24 15:11:40

标签: c# treeview

我有一个TreeView控件,我已经实现了拖放操作。 DragOver处理程序中有代码突出显示拖动节点的正确目标节点,该工作正常。我用鼠标左键移动节点,用右键复制它。问题是,当使用右键时,TreeView在拖动操作期间未正确显示所选节点。选择了正确的节点IS,我已经通过停止点进行了验证,但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;
    }

1 个答案:

答案 0 :(得分:0)

我自己遇到了这个问题并进行了本地发送消息调用以强制项目选择对我有用:

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