How can I tell a ContextMenu to place itself relatively to its control and not the cursor?

BoltClock picture BoltClock · Apr 25, 2011 · Viewed 9.4k times · Source

I have a button with a default command and a context menu for other available commands:

<Button Content="Do this" Height="23" Width="75" Command="local:MyCommands.ThisCommand">
    <Button.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Do this" Command="local:MyCommands.ThisCommand" />
            <MenuItem Header="Do that" Command="local:MyCommands.ThatCommand" />
        </ContextMenu>
    </Button.ContextMenu>
</Button>

By default, the context menu appears starting at the hot spot of the cursor:

However, I'd like it to appear at a fixed relative position, beneath the button (fake, edited screenshot):

Setting the context menu's Placement, PlacementRectangle and PlacementTarget properties doesn't seem to do anything; the context menu insists on hanging off the cursor wherever I right-click my button. Worse, focusing the button and hitting the menu key causes the context menu to sit in front of the button, blocking it completely.

So, how exactly do I specify that the context menu should appear beneath the button?

Answer

Bala R picture Bala R · Apr 25, 2011

Check out Remarks under ContextMenu.Placement

and try this

<Button Content="Do this" Height="23" Width="75" 
     ContextMenuService.Placement="Bottom"
     Command="local:MyCommands.ThisCommand">
    <Button.ContextMenu>
        <ContextMenu>
            <MenuItem Header="Do this" Command="local:MyCommands.ThisCommand" />
            <MenuItem Header="Do that" Command="local:MyCommands.ThatCommand" />
        </ContextMenu>
    </Button.ContextMenu>
</Button>