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