Проверяемый пункт меню с подменю - PullRequest
8 голосов
/ 25 февраля 2011

Можете ли вы иметь подменю с верхним уровнем, установленным для проверки в WPF?Я не могу заставить это работать.

<Window.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Top Level 1" IsCheckable="True" IsChecked="True">
            <MenuItem Header="Sub Level" />
            <MenuItem Header="Sub Level" />
        </MenuItem>
        <MenuItem Header="Top Level 2">
            <MenuItem Header="Sub Level" />
            <MenuItem Header="Sub Level" />
        </MenuItem>
    </ContextMenu>
</Window.ContextMenu>

Верхний уровень 1 можно проверить, но подуровни не отображаются.Есть мысли?

Ответы [ 2 ]

6 голосов
/ 25 февраля 2011

Если вы покопаетесь в MenuItem ControlTemplate, вы увидите, что он использует разные шаблоны в зависимости от свойства Role.

Справка:

Стили и шаблоны меню

<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>

Похоже, что он может разрешить проверку или подпункты по умолчанию.

Чтобы обойти это, используйте следующий код:

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>

Код:

private void MenuItem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    (sender as MenuItem).IsChecked = !(sender as MenuItem).IsChecked;
}

Я настоятельно рекомендую преобразовать / инкапсулировать эту функциональность в Attached Property или Behavior.

0 голосов
/ 26 февраля 2011

Добавить к ответу дециклона:

Поскольку после этого меню будет оставаться открытым, и если вы хотите, чтобы оно закрылось, вы можете закрыть меню, установив IsOpen = false в родительском контекстном меню:

private void MenuItem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
    (sender as MenuItem).IsChecked = !(sender as MenuItem).IsChecked; 
    ((sender as MenuItem).Parent as ContextMenu).IsOpen = false;
} 
...