2016-12-06 74 views
0

我在WPF中有一个databound层次菜单。所有项目都显示出来,但命令仅针对菜单的叶子,而不是具有子项目的项目。我猜想通过展开子菜单来覆盖命令... 即使对于带有子项的菜单项,我如何获得执行命令?WPF - 我如何给儿童的菜单项命令

我现在有什么是

<UserControl ...> 
    <WrapPanel> 
     <Menu> 
      <Menu.Resources> 
       <Style x:Key="MenuItemStyle" TargetType="MenuItem" d:DataContext="{d:DesignInstance local:TreeItem}"> 
        <Setter Property="Command" Value="{Binding DataContext.AddColumnCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"/> 
        <Setter Property="CommandParameter" Value="{Binding}"/> 
       </Style> 
      </Menu.Resources> 
      <MenuItem Header="Add ▼" ItemsSource="{Binding AvailableFields}"> 
       <MenuItem.ItemTemplate> 
        <HierarchicalDataTemplate DataType="{x:Type local:TreeItem}" ItemsSource="{Binding NestedItems}" ItemContainerStyle="{StaticResource MenuItemStyle}"> 
         <ContentPresenter Content="{Binding Annotation}"/> 
        </HierarchicalDataTemplate> 
       </MenuItem.ItemTemplate> 
      </MenuItem> 
     </Menu> 
    </WrapPanel> 
</UserControl> 

我发现了一个question with a similar name,但情况是不同的,它并没有一个很好的答案呢。

回答

0

显示所有项目,但命令只针对菜单的叶子,而不是具有子项目的项目。

是的,这是预期的行为,因为点击具有子项目的MenuItem应该展开子项目的子菜单。它不执行命令。

如果要展开的子项,然后执行,你可以处理菜单项的的PreviewMouseLeftButtonDown事件的命令:

<Style TargetType="{x:Type MenuItem}"> 
    <Setter Property="Command" Value="{Binding DataContext.AddColumnCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"/> 
    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="OnMouseDown" /> 
</Style> 

-

private void OnMouseDown(object sender, MouseButtonEventArgs e) 
{ 
    MenuItem mi = sender as MenuItem; 
    if (mi != null && mi.Command != null && mi.HasItems) 
     mi.Command.Execute(mi.CommandParameter); 
} 

注意处理的代码 - 事件视图后面并没有真正打破MVVM模式,因为您只是从代码隐藏中调用视图模型的命令,而不是从相同视图的XAML标记中调用视图模型。但是如果你不喜欢这种方法,你可以使用附加的行为:https://www.codeproject.com/articles/28959/introduction-to-attached-behaviors-in-wpf