I have created Context menu style with predefined MenuItems in it:
<Style TargetType="{x:Type ContextMenu}" x:Key="DataGridColumnFilterContextMenu">
<Setter Property="ContextMenu.Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="#868686"
BorderThickness="1"
Background="#FAFAFA">
<Grid MaxHeight="500">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel>
<MenuItem Header="Filtrēt" StaysOpenOnClick="True" Name="DynSearch">
<MenuItem.Icon>
<Image RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased"
Source="/Furniture;component/Resources/search4.png" />
</MenuItem.Icon>
</MenuItem>
<Separator Margin="20 5 20 0" Height="2" Width="Auto" />
<MenuItem Margin="5 5 0 0" StaysOpenOnClick="True" >
<MenuItem.Template>
<ControlTemplate >
<CheckBox Padding="15 0 0 0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >Iezīmēt/Atzīmēt visus</CheckBox>
</ControlTemplate>
</MenuItem.Template>
<MenuItem.Icon>
<Image RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased"
Source="/Furniture;component/Resources/search4.png" />
</MenuItem.Icon>
</MenuItem>
<Separator Margin="20 5 20 0" Height="2" Width="Auto" />
<RadioButton Margin="5 5 0 0" Padding="15 0 0 0" GroupName="Sorting" Content="Augoša secībā" IsChecked="True"/>
<RadioButton Margin="5 5 0 0" Padding="15 0 0 0" GroupName="Sorting" Content="Dilstoša secībā" />
<Separator Margin="20 5 20 5" Height="2" Width="Auto" />
</StackPanel>
<ScrollViewer Grid.Row="1"
Margin="1,0,1,0"
CanContentScroll="True"
VerticalScrollBarVisibility="Auto"
Grid.ColumnSpan="2">
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Cycle" />
</ScrollViewer>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Now I assigned style to new ContextMenu and wanted to assign Click event handler to MenuItem defined in style with header "Filtrēt". I tried do it like following:
ContextMenu cm = new ContextMenu();
cm.Style = Application.Current.Resources["DataGridColumnFilterContextMenu"] as Style;
var controlList = ((((cm.Template.LoadContent() as Border).Child as Grid).Children)[0] as StackPanel).Children;
MenuItem filterItem = (controlList[0] as MenuItem);
filterItem.Click += MiFiltre_Click;
And when I clicked debugger It didn't come to MiFiltre_Click method. I tried different events like MouseDown and PreviewMouseDown. Also I tried to bound ICommand and this also didn't work.
Then I searched this question and realized that cm.Template.LoadContent() may actually create new instance of my ContextMenu template and I am trying to bound my event handler to different control instance. Then I tried to get ContextMenu node controls with VisualTreeHelper and LogicalTreeHelper and this also didn't work.
So here are questions:
I'm going to assume this menu Style is defined in a resource dictionary named "MyResources.xaml".
Create a Class file in the same project folder, and call it "MyResources.xaml.cs".
Make it a partial class like this:
namespace WhateverNamespace
{
public partial class MyResources
{
private void FilterMenuItem_Click(object sender, RoutedEventArgs e)
{
MenuItem mi = (MenuItem)sender;
// Below, PlacementTarget is the control the user right-clicked on.
// Use that directly if you want that instead of its viewmodel.
// This works with the conventional ContextMenu defined below.
//ViewModel viewModel = ((FrameworkElement)((ContextMenu)mi.Parent).PlacementTarget).DataContext as ViewModel;
// This works with your template design. The only difference is
// TemplatedParent instead of Parent.
ViewModel viewModel =
((FrameworkElement)((ContextMenu)mi.TemplatedParent).PlacementTarget)
.DataContext as ViewModel;
MessageBox.Show("FilterMenuItem_Click");
}
}
}
Give the resource dictionary an x:Class
attribute:
<ResourceDictionary
x:Class="WhateverNamespace.MyResources"
Wire up the handler:
<MenuItem
Click="FilterMenuItem_Click"
Header="Filtrēt"
StaysOpenOnClick="True"
Name="DynSearch">
By the way, you don't need to mess with styles and templates to create a ContextMenu
resource:
<ContextMenu x:Key="DataGridColumnFilterContextMenu">
<MenuItem
Click="FilterMenuItem_Click"
Header="Filtrēt"
StaysOpenOnClick="True"
Name="DynSearch">
<MenuItem.Icon>
<Image
RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased"
Source="/Furniture;component/Resources/search4.png"
/>
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem StaysOpenOnClick="True">
<MenuItem.Header>
<CheckBox>Iezīmēt/Atzīmēt visus</CheckBox>
</MenuItem.Header>
<MenuItem.Icon>
<Image
RenderOptions.BitmapScalingMode="NearestNeighbor"
RenderOptions.EdgeMode="Aliased"
Source="/Furniture;component/Resources/search4.png"
/>
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem>
<MenuItem.Header>
<RadioButton GroupName="Sorting" Content="Augoša secībā" IsChecked="True"/>
</MenuItem.Header>
</MenuItem>
<MenuItem>
<MenuItem.Header>
<RadioButton GroupName="Sorting" Content="Dilstoša secībā" IsChecked="True"/>
</MenuItem.Header>
</MenuItem>
</ContextMenu>