0

我知道有一些相关的问题,但没有一个能帮助我找到问题。

大多数答案建议实施 CanExecuteChanged ,如this answer所示。好吧,这不是我的问题的解决方案。我有一个 RelayCommand 的实现,类似于Josh Smith 的实现。(类似,因为我们的实现增加了更多细节,但核心实现是相同的。)

在网上搜索时,我还了解到,如果没有焦点元素,路由将在 ContextMenu 处停止,并且不会到达 MenuItem。在这种情况下会有所帮助的解决方案如下所示
但是,如果确实没有任何重点元素,我与 Snoop 进行了核对,并了解到这不是问题所在。无论如何,修复并没有帮助。
此外,我在一个测试项目中模拟了这个问题并且能够修复它。所以修复通常有效,它只是没有帮助我。但是,我认为仍有机会我必须稍微调整修复以使其正常工作。我尝试MyControl了而不是ContextMenu作为 AncestorType 并且我尝试PlacementTarget.Tag了而不是仅仅PlacementTarget作为Path但我不知道还有什么办法让它工作(假设这是错误)。

有趣的是,当我手动调用 CommandManager.InvalidateRequerySuggested() 时,它甚至不起作用。我添加了一个在 ContextMenuOpening 上引发的命令。我认为这会迫使 CanExecute 被执行,但似乎我错了。

因此,我现在正在寻找在打开 ContextMenu 时未引发处理程序的进一步原因CanExecute以及如何解决该问题。

这是我的 XAML 代码(包括EventTriggerfor 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();
}
4

1 回答 1

0

OnContextMenuOpeningContextMenu控件上听错了。它永远不会着火!MyControl相反,请在您的控件上监听这个事件。

于 2018-11-14T14:49:03.927 回答