Checkable MenuItem With Sub Menus
If you dig into MenuItem
's ControlTemplate
, you will see that it uses different templates depending on it's Role
property.
Reference:
Menu Styles and Templates
<Style x:Key="{x:Type MenuItem}"
TargetType="{x:Type MenuItem}">
<Setter Property="OverridesDefaultStyle"
Value="True" />
<Style.Triggers>
<Trigger Property="Role"
Value="TopLevelHeader">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.TopLevelHeaderTemplateKey}}" />
<Setter Property="Grid.IsSharedSizeScope"
Value="true" />
</Trigger>
<Trigger Property="Role"
Value="TopLevelItem">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.TopLevelItemTemplateKey}}" />
</Trigger>
<Trigger Property="Role"
Value="SubmenuHeader">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}" />
</Trigger>
<Trigger Property="Role"
Value="SubmenuItem">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.SubmenuItemTemplateKey}}" />
</Trigger>
</Style.Triggers>
</Style>
Seems like it can either allow checking or subitems by default.
To workaround that, use following code:
XAML:
<ContextMenu>
<MenuItem Header="Top Level 1"
Mouse.PreviewMouseUp="MenuItem_MouseLeftButtonUp">
<MenuItem Header="Sub Level" />
<MenuItem Header="Sub Level" />
</MenuItem>
<MenuItem Header="Top Level 2">
<MenuItem Header="Sub Level" />
<MenuItem Header="Sub Level" />
</MenuItem>
</ContextMenu>
Code behind:
private void MenuItem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
(sender as MenuItem).IsChecked = !(sender as MenuItem).IsChecked;
}
I strongly recommend converting/encapsulating this piece of functionality into an Attached Property
or a Behavior
.