I have this context menu resource:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ContextMenu x:Key="FooContextMenu">
<ContextMenu.CommandBindings>
<CommandBinding Command="Help" Executed="{Binding ElementName=MainTabs, Path=HelpExecuted}" />
</ContextMenu.CommandBindings>
<MenuItem Command="Help">
<MenuItem.Icon>
<Image Source="../Resources/Icons/Help.png" Stretch="None" />
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</ResourceDictionary>
I want to re-use it in two places. Firstly I’m trying to put it in a DataGrid:
<DataGrid ContextMenu="{DynamicResource FooContextMenu}">...
The ContextMenu itself works fine, but with the Executed="..." I have right now breaks the application and throws:
A first chance exception of type ‘System.InvalidCastException’
occurred in PresentationFramework.dllAdditional information: Unable to cast object of type
‘System.Reflection.RuntimeEventInfo’ to type
‘System.Reflection.MethodInfo’.
If I remove the entire Executed="..." definition, then the code works (and the command does nothing/grayed out). The exception is thrown as soon as I right click the grid/open the context menu.
The DataGrid is placed under a few elements, but eventually they all are below a TabControl (called MainTabs) which has ItemsSource set to a collection of FooViewModels, and in that FooViewModel I have a method HelpExecuted which I want to be called.
Let’s visualize:
- TabControl (
ItemsSource=ObservableCollection<FooViewModel>,x:Name=MainTabs)- Grid
- More UI
- DataGrid (with context menu set)
- More UI
- Grid
Why am I getting this error and how can I make the context menu command to “target” the FooViewModel‘s HelpExecuted method?
Unfortunately you cannot bind
Executedfor aContextMenuas it is an event. An additional problem is that theContextMenudoes not exist in theVisualTreethe rest of your application exists. There are solutions for both of this problems.First of all you can use the
Tagproperty of the parent control of theContextMenuto pass-through theDataContextof your application. Then you can use anDelegateCommandfor yourCommandBindingand there you go. Here’s a small sample showingView,ViewModeland theDelegateCommandimplementation you would have to add to you project.DelegateCommand.cs
MainWindowView.xaml
MainWindowView.xaml.cs
MainWindowViewModel.cs
FooViewModel.cs