関連する質問がいくつかあることは知っていますが、どれも問題を見つけるのに役立ちませんでした。
ほとんどの回答は、この回答に示されているようにCanExecuteChanged を実装することを提案しています。まあ、それは私の問題の解決策ではありません。Josh Smith の実装に似た RelayCommand の実装があります。(同様に、私たちの実装はより多くの詳細を追加しますが、コアの実装は同じです。)
インターネットを検索しているときに、フォーカスされた要素がない場合、ルーティングは ContextMenu で停止し、MenuItem に到達しないこともわかりました。その場合に役立つ解決策をここに示します。
しかし、本当にフォーカスされた要素がないかスヌープに確認したところ、それは問題ではないことがわかりました。とにかく、修正は役に立ちませんでした。
また、テスト プロジェクトでその問題をシミュレートし、修正することができました。したがって、修正は一般的に機能しますが、役に立たないだけです。ただし、機能させるために修正を少し調整する必要がある可能性はまだあると思います。as AncestorTypeMyControl
の代わりに試してみました。 asの代わりに試しました。ContextMenu
PlacementTarget.Tag
PlacementTarget
Path
しかし、それを機能させるために他に何をしようとしているのかわかりません(これがバグであると仮定して)。
面白いことに、手動で CommandManager.InvalidateRequerySuggested() を呼び出しても機能しません。ContextMenuOpening で発生するコマンドを追加しました。これにより CanExecute が強制的に実行されると思いましたが、間違っているようです。
そのため、ContextMenu が開かれたときにハンドラーが発生しない理由と、CanExecute
それを修正する方法をさらに探しています。
これが私のXAMLコードです(EventTrigger
forを含むContextMenuOpening
):
<MyControl>
<MyControl.ContextMenu>
<ContextMenu>
<MenuItem Header="..."
Command="{Binding MyCommand}"
CommandParameter="{Binding}"
CommandTarget="{Binding Path=PlacementTarget,
RelativeSource={RelativeSource
AncestorType={x:Type ContextMenu}}}"/>
</ContextMenu>
</MyControl.ContextMenu>
<i:Interaction.Triggers>
<i:EventTrigger EventName="ContextMenuOpening">
<i:InvokeCommandAction Command="{Binding OnContextMenuOpening}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</MyControl>
MyCommand
(Can)Execute ハンドラの定義は次のとおりです。
internal static readonly ICommandEx MyCommand =
new RelayCommand(OnMyCommand, OnCanMyCommand);
private static void OnMyCommand(object parameter) { ... }
private static bool OnCanMyCommand(object parameter) { ... }
の CanExecute を強制的に発生させようとしたOnContextMenuOpening
ハンドラーは次のとおりです。MyCommand
private static void OnContextMenuOpening(object parameter)
{
CommandManager.InvalidateRequerySuggested();
}