你有三个选择:
1)您可以注册您的 CommandBinding 来处理预览事件,而不是常规事件或除了常规事件之外:
CommandBinding cb = new CommandBinding(ApplicationCommands.SelectAll);
cb.PreviewCanExecute += OnCanExecuteSelectAll;
cb.PreviewExecuted += OnExecutedSelectAll;
但请注意 - 如果您已注册 PreviewExecuted,则在通过 CommandBinding 注册处理程序时,即使您将 e.Handled 显式设置为 false,已执行的处理程序也永远不会运行。不过,对于 PreviewCanExecute/CanExecute 事件对,它确实可以正常工作。这是实现 CommandBinding 类的方式。
因此,仅当您不希望基类命令处理程序运行时才使用 PreviewExecuted。
2) 或者,您可以直接通过 CommandManager 注册您的命令处理程序:
CommandManager.AddPreviewCanExecuteHandler(this, OnCanExecuteSelectAll);
CommandManager.AddPreviewExecutedHandler(this, OnExecutedSelectAll);
不过,这不是一个类处理程序,因此您需要为每个实例执行此操作。然后在您的处理程序中,您需要检查天气这是您感兴趣的命令(事件参数中有对该命令的引用)。注意:您仍然必须注册 CommandBinding,但如果您只想直接在 CommandManager 上添加处理程序 - 您不需要使用该命令绑定注册任何处理程序。
3)或者你可以做一些黑客(不是真正的黑客):
this.AddHandler(CommandManager.CanExecuteEvent, new CanExecuteRoutedEventHandler(OnCanExecuteSelectAll), true);
this.AddHandler(CommandManager.ExecutedEvent, new ExecutedRoutedEventHandler(OnExecutedSelectAll), true);
这样您就可以注册命令事件处理程序,以便即使它们已经被处理,它们也会被执行。
与上述要点一样,您需要注册命令绑定才能触发 CommandManager 事件。
这与上面第 2 点中的内容几乎相同,但是当您调用 CommandManager.Add[四个事件之一]Handler 时,命令管理器使用两个参数版本在控件上调用 AddHandler。