If you delve into the MenuItem ControlTemplate , you will see that it uses different templates depending on this 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>
It looks like it can either allow validation, or the default subelements.
To get around this, use the 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 highly recommend converting / encapsulating this functionality into an Attached Property or Behavior .
decyclone
source share