2

I have a rectangle.The rectangle has a custom contextmenu(just some simple changes made within the ControlTemplae of <ContextMenu.Template>).What i want is,on left mouse click,the contextmenu will popup.

I tried adding rectangle1.contextmenu.isopen=true in the rectangle's MouseDown event.Yes,it opens the contextmenu.However, the contextmenu is set to open/pop up above(on top) of the rectangle,i did it by simply adding ContextMenuService.Placement="top" to the rectangle's XAML.But if i use rectangle1.contextmenu.isopen=true in the rectangle's MouseDown event, then the contextmenu pops up but in the wrong place,it doesn't stay on top any more, rather it follows the mouse.E.g. If i click the right corner of the rectangle,the contextmenu opens/pops up in the right.This behaviour is very strange,i don't know why this is happening.

Anyway,how do i open the contextmenu at the top of the rectangle on left mouse click?

UPDATE

What's strange is that no matter what code i add to any of the mouseevents,the context menu loses it's placement ! E.g.If i even add MsgBox("abc") on mouseDown event, and then right click on the rectangle, the context menu is not on top!!

  • Possible duplicate of [WPF Context menu on left click](https://stackoverflow.com/questions/4305565/wpf-context-menu-on-left-click) – Rekshino Feb 26 '18 at 15:04
  • i've been through that SO post, but with no luck, mine is a rect,please read about my problem(contextmenu not maintaining position) –  Feb 26 '18 at 15:05

2 Answers2

5

As I can see from MSDN reference ContextMenu.Placement

When the ContextMenu is assigned to the FrameworkElement.ContextMenu or FrameworkContentElement.ContextMenu property, the ContextMenuService changes this value of this property when the ContextMenu opens. If the user opens the ContextMenu by using the mouse, Placement is set to MousePoint. If the user opens the ContextMenu by using the keyboard, Placement is set to Center. If you want to change the position of the ContextMenu, set the ContextMenuService.Placement property on the FrameworkElement or FrameworkContentElement.

So since you do it not via ContextMenuService you should change Placement and PlacementTarget by yourself.

private void Mouse_Down(object sender, MouseButtonEventArgs e)
{
    var cm = ContextMenuService.GetContextMenu(sender as DependencyObject);
    if (cm==null)
    {
        return;
    }
    cm.Placement = PlacementMode.Top;
    cm.PlacementTarget = sender as UIElement;
    cm.IsOpen = true;
}
Rekshino
  • 6,954
  • 2
  • 19
  • 44
1

I think this is what you're going for?

rect.ContextMenu.PlacementTarget = rect;

rect.ContextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.Top;
rect.ContextMenu.IsOpen = true;

// if you want it to be at the top and come down over the rectangle
rect.ContextMenu.VerticalOffset = rect.ContextMenu.ActualHeight;
Marsh
  • 188
  • 2
  • 10
  • i added the code to the `MouseDown` event and the reult is more strange.....now it pops up over the rect –  Feb 26 '18 at 16:03