调用 ContextMenu 以打开

ser*_*hio 5 .net wpf contextmenu click double-click

我需要做一些像谷歌地图做的事情(但在WPF):

  • RightClick地图上时,我有一个 ContextMenu。
  • RightDoubleClicking我有 UnZoom 动作时。

所以,显然,这在 WPF 中有点困难......在挣扎和搜索了很多之后,阅读了那些“我们无法预测未来”的人(我问自己谷歌是如何预测的),我决定“等待“ SystemInformation.DoubleClickTime,然后才显示上下文菜单。

当然,这不是理想的,甚至人类可观察到的,但我不知道其他方法。

所以,我对以下代码的问题是(我有一个自定义画布):

ContextMenuEventArgs lastContextMenuEventArgs = null;
bool? lastContextMenuEventArgsHandled = null;

protected override void OnContextMenuOpening(ContextMenuEventArgs e)
{
    lastContextMenuEventArgs = e;
    lastContextMenuEventArgsHandled = e.Handled;

    e.Handled = true;
    //base.OnContextMenuOpening(e);
}

bool rightMouseClickedOnce = false;
protected override void OnPreviewMouseRightButtonUp(MouseButtonEventArgs e)
{
    //base.OnPreviewMouseRightButtonUp(e);

    Console.WriteLine(">>>>>>>>>>> OnPreviewMouseRightButtonUp");
    if (!rightMouseClickedOnce)
    {
        rightMouseClickedOnce = true;
        Thread thread = new Thread(
            new System.Threading.ThreadStart(
                delegate()
                {
                    Thread.Sleep(System.Windows.Forms.SystemInformation.DoubleClickTime);
                    this.Dispatcher.Invoke(
                        System.Windows.Threading.DispatcherPriority.Background,
                        new Action(
                            delegate()
                            {
                                if (rightMouseClickedOnce)
                                {
                                    Console.WriteLine(">>>>>>>>>>> Right Click");
                                    rightMouseClickedOnce = false;
                                    base.OnPreviewMouseRightButtonUp(e);

                                    if (lastContextMenuEventArgsHandled.HasValue)
                                    {
                                        Console.WriteLine(">>>>>>>>>>> lastContextMenuEventArgsHandled");
                                        lastContextMenuEventArgs.Handled = lastContextMenuEventArgsHandled.Value;
                                        base.OnContextMenuOpening(lastContextMenuEventArgs);
                                        lastContextMenuEventArgsHandled = null;
                                    }
                                    //if (this.ContextMenu != null)
                                    //{
                                    //  this.ContextMenu.PlacementTarget = this;
                                    //  this.ContextMenu.IsOpen = true;
                                    //}
                                }
                            }
                    ));
                }
        ));
        thread.Start();
    }
    else if (rightMouseClickedOnce)
    {
        Console.WriteLine(">>>>>>>>>>> Right Double Click");
        rightMouseClickedOnce = false;
        base.OnPreviewMouseRightButtonUp(e);
        this.OnMouseRightDoubleClick(e);
    }

}
Run Code Online (Sandbox Code Playgroud)

一切正常,但有一个小问题:base.OnContextMenuOpening(lastContextMenuEventArgs);似乎不起作用......

我之前设置的

if (this.ContextMenu != null)
{
  this.ContextMenu.PlacementTarget = this;
  this.ContextMenu.IsOpen = true;
}
Run Code Online (Sandbox Code Playgroud)

这奏效了,但最终这会阻止子 contextMenu 元素的打开,并始终打开父(画布)contextMenu。

我可以只调用 contextMenu 事件吗?