【问题标题】:WPF: DoDragDrop getting interrupted when clicking Right/Middle Mouse buttonWPF:单击鼠标右键/中键时 DoDragDrop 被中断
【发布时间】:2012-10-16 13:27:13
【问题描述】:

我已经扩展了 Canvas {System.Windows.Controls} 和可拖动到 Canvas 中的项目。 在拖动过程中,我有 OnDragOver 事件,当用户单击并按住鼠标中键时,我会在其中进行平移。

Item 网站上:DoDragDrop - 常用拖动功能
Canvas 网站上:OnDragOver - 平移画布

所以用户可以同时拖动和平移。

在我搬到新的笔记本电脑(联想)和 Visual Studio 2012(2010 之前)之前,一切都很好。现在,当我按下鼠标中键(或右键)时,会立即触发 Canvas 的 OnMouseMove 事件。之后立即停止拖动,也不再平移。

我的同事尝试从 Visual Studio 2010 运行相同的代码,并且运行正常。他设置了他的版本,所以我尝试了一下,结果是一样的 - 在我的笔记本电脑上,我在拖动过程中无法平移..

有人知道是什么问题吗?硬件、软件、联想、Windows?

项目信息:WPF、DevExpress 12.1、.NET 4、Windows 7 Proffesional、VS 2012

请记住,我在 WPF 中还是新手 :)

【问题讨论】:

  • 您确定是 .NET 4 而不是 .NET 4.5?
  • 我确定。我什至尝试在 .NET 4.5 上运行它,结果相同。

标签: c# wpf drag-and-drop devexpress mousemove


【解决方案1】:

只是回答我自己的问题,也许它会对某人有用。

我没有发现问题出在哪里,但我的结论是,在某些 PC 上,当用户在拖动时按下鼠标中键/右键时,DragDrop 可能会中断。

要覆盖此行为,您需要将 QueryContinueDragHandler 添加到 DragDrop。然后在您自己的处理程序中使用您的逻辑来响应鼠标/键盘输入。

所以我的代码如下所示:

DragDrop.AddQueryContinueDragHandler(this, QueryContinueDragHandler);
DragDrop.DoDragDrop(this, dataObject, DragDropEffects.Copy);
DragDrop.RemoveQueryContinueDragHandler(this, QueryContinueDragHandler);

和自定义处理程序:

/// <summary>
/// Own handler. This event is raised when something happens during DragDrop operation (user presses Mouse button or Keyboard button...)
/// Necessary to avoid canceling DragDrop on MouseMiddleButon on certain PCs.
/// Overrides default handler, that interrupts DragDrop on MouseMiddleButon or MouseRightButton down.
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
private void QueryContinueDragHandler(Object source, QueryContinueDragEventArgs e)
{
    e.Handled = true;

        // if ESC
        if (e.EscapePressed)
        {
            //  -->  cancel DragDrop
            e.Action = DragAction.Cancel;

            return;
        }

        // if LB
        if (e.KeyStates.HasFlag(DragDropKeyStates.LeftMouseButton))
        {
            //  -->  continue dragging
            e.Action = DragAction.Continue;
        }
        // if !LB (user released LeftMouseButton)
        else
        {
            // and if mouse is inside canvas
            if (_isMouseOverCanvas)
            {
                //  -->  execute Drop
                e.Action = DragAction.Drop;
            }
            else
            {
                //  -->  cancel Drop 
                e.Action = DragAction.Cancel;                    
            }

            return;
        }

        // if MB
        if (e.KeyStates.HasFlag(DragDropKeyStates.MiddleMouseButton))
        {
            //  -->  continue dragging
            e.Action = DragAction.Continue;
        }    
}

【讨论】:

  • 请注意,在DragDrop.AddQueryContinueDragHandler(this, QueryContinueDragHandler); 之后执行DragDrop.RemoveQueryContinueDragHandler(this, QueryContinueDragHandler); 不会删除处理程序,因为方法名称被转换为委托对象两次并且这些委托不相等。
  • 谢谢Gman,我还没有意识到这一点。所以解决方案是创建本地委托并将其作为参数传递给两个方法,对吗?
  • 是的,没错。 (类似这样的:QueryContinueDragEventHandler d = QueryContinueDragHandler;
猜你喜欢
  • 2012-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多