事後にかなり答えていることに気づきましたが、同じ問題に遭遇し、以前の答えは複数の異なるコマンドへのバインドを困難にしているように見えました。私が到達したソリューションは、MatrixManAtYrServiceのソリューションと非常によく似ており、次の3つの部分で機能します。
1)ItemContainerStyleプロパティを使用してコマンドをViewModelのコマンドにバインドします。これは、前の回答と同じです。1つの例外は、CommandParameterをMenuItemにバインドすることです。
<Setter Property="CommandParameter" Value="{Binding RelativeSource={RelativeSource Self}}"/>
2)カスタムクラスを作成して、各MenuItemの外観と動作を定義します。メニューのItemsSourceは、これらのリストに設定されます。これは他の答えと同じです。ただし、私の実装では、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でも、多少の調整を加えて機能するはずです。