Interesting problem related to firing commands from context menu items…
I want to fire a command to insert a row in my control, InsertRowCmd. This command needs to know where to insert the row.
I could use Mouse.GetPosition(), but that would get me the position of the mouse currently, which would be over the menu item. I want to get the origin of the context menu instead.
Does any one have any suggestions on how to pass the origin of the context menu as a parameter to the command?
Sample code:
<UserControl x:Name="MyControl">
<!--...-->
<ContextMenu x:Name="menu">
<MenuItem Header="Insert Row" Command="{x:Static customCommands:MyCommands.InsertRowCmd}" CommandParameter="?"/>
</ContextMenu>
</UserControl>
My current ideas are as follows:
-Use click handler instead so that I can find the origin in code. The problem is that I would then have to handle enabling/disabling.
-Handle click event and save the origin of the context menu. Pass this saved information into the command. I have verified that click events fire before the command is executed.
Any ideas?
EDIT:
I’m using Josh Smith’s CommandSinkBinding to route the command handling into my ViewModel class. So the code that handles the command execution knows nothing about the view.
You’ll need to use
TranslatePointto translate the top-left (0, 0) of theContextMenuto a coordinate in the containing grid. You could do so by binding theCommandParameterto theContextMenuand use a converter:Another approach would be an attached behavior that automatically updates an attached readonly property of type
Pointwhenever theContextMenuis opened. Usage would look something like this:So the
TrackOpenLocationattached property does the work of attaching to theContextMenuand updating a second attached property (OpenLocation) whenever theContextMenuis opened. Then theMenuItemcan just bind toOpenLocationto get the location at which theContextMenuwas last opened.