我意识到我在事后回答了这个问题,但我遇到了同样的问题,以前的答案似乎使绑定到多个不同的命令变得困难。我到达的解决方案与 MatrixManAtYrService 非常相似,分为 3 个部分:
1)使用 ItemContainerStyle 属性将命令绑定到 ViewModel 中的命令——这与前面的答案相同。一个例外是我将 CommandParameter 绑定到 MenuItem。
<Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource Self}}"/>
2) 创建一个自定义类来定义每个 MenuItem 的外观和行为。菜单的 ItemsSource 将设置为这些列表。这与其他答案相同。但是,在我的实现中,我为类提供了一个 Action,以便在调用 MenuItemCommand 时执行。我还包括了一个允许禁用 MenuItem 的布尔值。
public class MenuAction
{
public string Name { get => name; set => name = value; }
public Action Action { get => action; set => action = value; }
public bool CanExecute { get => canExecute; set => canExecute = value; }
}
3) 在命令执行路由控制到MenuAction 中的代表。
public void HandleCommand(object sender)
{
MenuItem clickedMenuItem = sender as MenuItem;
MenuAction menuAction = clickedMenuItem?.DataContext as MenuAction;
if(menuAction != null)
menuAction.Action();
}
public bool CanMenuItemExecute(object sender)
{
MenuItem clickedMenuItem = sender as MenuItem;
MenuAction menuAction = clickedMenuItem?.DataContext as MenuAction;
if (menuAction != null)
return menuAction.CanExecute;
else
return false;
}
这应该允许您在列表中定义命令的所有行为。虽然它在技术上绑定到单个命令,但它在功能上类似于拥有多个不同的命令。同样的方法也应该适用于嵌套的 MenuItems 和 HierarchicalDataTemplates 并进行一些调整。