Call ContextMenu to open

I need to do something like Google Maps (but in WPF ):

  • when RightClick on the map I have ContextMenu.
  • When RightDoubleClicking I have an UnZoom action.

So, apparently, this is a little difficult in WPF ... After reading a lot and a lot, read the people who comment that “we cannot predict the future” (I ask myself how Google predicts this), I decided to “wait” SystemInformation.DoubleClickTime and only then display contextMenu.

Of course, this is not ideal, even a human observable, but I do not know another method.

So, the problem that I have with the following code: (I have a custom canvas):

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

Everything works fine, but a little problem: base.OnContextMenuOpening(lastContextMenuEventArgs); doesn't seem to work ...

I installed before

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

and it worked, but finally it blocks the contextMenu children from opening and always opens the parent (canvas) contextMenu.

Can I just call the contextMenu event?

+4
source share
1 answer

I don’t know much about WPF, but can you show the menu, say, a pixel from the cursor and see if the user right-clicks again in the same place and double-click? I used a similar technique once in a game, and it performed quite well.
The "fade in" menu (possibly out, too) animation can make it even better.

0
source

Source: https://habr.com/ru/post/1332811/


All Articles