Вызвать ContextMenu, чтобы открыть - PullRequest
4 голосов
/ 20 декабря 2010

Мне нужно сделать что-то вроде Google Maps (но в WPF):

  • , когда RightClick на карте, у меня есть ContextMenu.
  • когда RightDoubleClicking у меня есть действие UnZoom.

Так что, очевидно, это немного сложно в WPF ... После долгих попыток и поиска, читайте людей, которые сочетаютсячто «мы не можем предсказать будущее» (я спрашиваю себя, как Google это предсказывает), я решил «подождать» SystemInformation.DoubleClickTime и только затем отобразить contextMenu.

Конечно, это не идеал, даже наблюдаемый человеком, но я не знаю другого метода.

Итак, проблема, с которой я сталкиваюсь со следующим кодом (у меня есть пользовательскийХолст):

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 и всегда открывает родительский (canvas) contextMenu.

Могу ли я просто вызвать событие contextMenu?

1 Ответ

0 голосов
/ 20 декабря 2010

Я мало что знаю о WPF, но можете ли вы показать меню, скажем, в пикселе от курсора и посмотреть, нажимает ли пользователь снова правой кнопкой мыши в том же месте и во время двойного щелчка в системе?Я однажды использовал подобную технику в игре, и она работала достаточно хорошо.
Анимация меню "Fade In" (опционально, тоже) может сделать его еще лучше.

...