我在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 :(得分:0)
显示所有项目,但命令仅针对菜单的叶子而不是具有子项的项目。
是的,这是预期的行为,因为点击带有子项的MenuItem应该扩展子项的子菜单。它不执行命令。
如果要扩展子项并执行命令,可以处理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