当前位置: 动力学知识库 > 问答 > 编程问答 >

c# - TreeView not visually updating while right mouse dragging

问题描述:

I have a TreeView control in which I have implemented drag and drop. There is code in the DragOver handler to highlight the correct destination node for the dragged node, which works fine. I use the left mouse button to move a node, and the right button to copy it. The problem is that when using the right button, the TreeView is not properly displaying the selected node during the drag action. The proper node IS being selected, which I have verified with a stop point, but the TreeView itself is not showing this. It does show it when the left mouse button is being used.

 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;

}

网友答案:

I encountered this problem myself and making a native send message call to force item selection worked for me:

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
    }
}

To use it:

targetNode.ForceSelection(NativeExtensions.UnmanagedTreeNodeSelectType.DragAndDropTarget);

分享给朋友:
您可能感兴趣的文章:
随机阅读: