【问题标题】:Invoke a ContextMenu to open调用 ContextMenu 打开
【发布时间】:2011-05-28 10:31:27
【问题描述】:

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

  • 当RightClick 在地图上时,我有一个上下文菜单。
  • 当 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);
    }

}

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

我之前设置的

if (this.ContextMenu != null)
{
  this.ContextMenu.PlacementTarget = this;
  this.ContextMenu.IsOpen = true;
}

这行得通,但最终这会阻止子 contextMenu 元素打开,并始终打开父(画布)contextMenu。

我可以只调用 contextMenu 事件吗?

【问题讨论】:

    标签: .net wpf click contextmenu double-click


    【解决方案1】:

    我对 WPF 了解不多,但是您能否显示菜单,例如,距离光标一个像素,并查看用户是否在同一位置再次右键单击并在系统双击时间内?我曾经在游戏中使用过类似的技术,它的表现非常好。
    菜单“淡入”(也可以选择淡出)动画可以让它变得更好。

    【讨论】:

    • 问题在于: a) 关联的菜单在鼠标位置自动打开(这是因为我阻止了上下文菜单的打开); b) 我不应该阻止子元素上下文菜单(例如,City contextMenu 或 Road ContemtMenu)。孩子们也通过相同的事件 conteextMenuOpening...
    猜你喜欢
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 2014-11-06
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 2012-06-02
    相关资源
    最近更新 更多