我知道有一些相关的问题,但没有一个能帮助我找到问题。
大多数答案建议实施 CanExecuteChanged ,如this answer所示。好吧,这不是我的问题的解决方案。我有一个 RelayCommand 的实现,类似于Josh Smith 的实现。(类似,因为我们的实现增加了更多细节,但核心实现是相同的。)
在网上搜索时,我还了解到,如果没有焦点元素,路由将在 ContextMenu 处停止,并且不会到达 MenuItem。在这种情况下会有所帮助的解决方案如下所示。
但是,如果确实没有任何重点元素,我与 Snoop 进行了核对,并了解到这不是问题所在。无论如何,修复并没有帮助。
此外,我在一个测试项目中模拟了这个问题并且能够修复它。所以修复通常有效,它只是没有帮助我。但是,我认为仍有机会我必须稍微调整修复以使其正常工作。我尝试MyControl
了而不是ContextMenu
作为 AncestorType 并且我尝试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) { ... }
这是我的OnContextMenuOpening
处理程序,我试图强制MyCommand
提升 CanExecute :
private static void OnContextMenuOpening(object parameter)
{
CommandManager.InvalidateRequerySuggested();
}