这让我疯了几天了!
我无法让命令的Executed部分触发菜单中“Level 1”以下的任何内容。我可以看到总是在所有菜单项上调用'CanExecute'回调,并且回调总是返回true。
请有人指出我正确的方向吗?我知道我可以在MyTypes中添加ICommand的实现:MyMenuDescriptorType但这不适合我想要实现的模型。
非常感谢提前
private void CreateActionCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
e.Handled = true;
}
private void CreateActionCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
Debug.WriteLine("This only happens on Level 1");
}
<UserControl.Resources>
<ResourceDictionary>
<RoutedUICommand x:Key="CreateAction" Text="CreateAction"/>
</ResourceDictionary>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<Menu>
<Menu.CommandBindings>
<CommandBinding Command="{StaticResource CreateAction}" Executed="CreateActionCommand_Executed" CanExecute="CreateActionCommand_CanExecute"/>
</Menu.CommandBindings>
<Menu.Resources>
<Style x:Key="MyMenuStyle" TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding Description}"/>
<Setter Property="Command" Value="{StaticResource CreateAction}" />
<Setter Property="CommandParameter" Value="{Binding}"/>
<Setter Property="CommandTarget" Value="{Binding Path=., RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Menu}}}"/>
</Style>
</Menu.Resources>
<MenuItem Header="Root Level">
<MenuItem Header="Level 1" ItemsSource="{Binding MyListOfThings}" ItemContainerStyle="{StaticResource MyMenuStyle}">
<MenuItem.Resources>
<HierarchicalDataTemplate
DataType="{x:Type MyTypes:MyMenuDescriptorType}"
ItemsSource="{Binding Path=Children}"
ItemContainerStyle="{StaticResource MyMenuStyle}"/>
</MenuItem.Resources>
</MenuItem>
</MenuItem>
</Menu>
</Grid>
更新:我已经解决了出了什么问题。我的简化示例没有更新属性'MyListOfThings'。如果我在Menu的PreviewMouseLeftButtonDown事件中更新'MyListOfThings',那么控件会执行奇怪的操作并且命令不会触发。但是,如果我在MouseOver事件中更新属性,那么一切都按预期工作!
我不确定为什么会这样。也许有人可以解释一下?
答案 0 :(得分:0)
您可以尝试实施DelegateCommand,您可以找到snippet code here。
在您的MenuItem之后,将如下所示:
<MenuItem Header="DoSomething" Command="{Binding DoSomethingCommand}"/>
并在您的ViewModel中:
public MainViewModel()
{
DoSomethingCommand= new DelegateCommand(DoSomethingCommandExec, DoSomethingCommandCanExec);
}
public ICommand DoSomethingCommand{ get; private set; }
private bool DoSomethingCommandCanExec()
{
return true;
}
private void DoSomethingCommandExec()
{
// DoSomethingCommand
}
我认为这是实施它的好方法。每个MenuItem都有一个Command。您可以将Menuitems放入MenuItem,它可以绑定到与此处相同的命令。
像:
<MenuItem Header="DoSomething" Command="{Binding DoSomethingCommand}">
<MenuItem Header="DoSomething" Command="{Binding DoSomethingCommand}"/>
</MenuItem>
希望帮助。
问候!
答案 1 :(得分:0)
基于this问题。它对我有用:
HAML:
eventList.clear();
cs:
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication3"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<ContextMenu x:Key="ContextMenu1">
<MenuItem Header="Menu1" Command="{Binding PlacementTarget.Tag.Menu1Executed, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
</ContextMenu>
</ResourceDictionary>
</Window.Resources>
<Grid ShowGridLines="True" ContextMenu="{DynamicResource ContextMenu1}" Tag="{Binding}">
<Grid.RowDefinitions>
<RowDefinition Height="100*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="1" Content="Content" Margin="2"/>
</Grid>