WPF 两个命令处理程序,一个命令 [英] WPF Two Commands handlers, One Command

查看:26
本文介绍了WPF 两个命令处理程序,一个命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我来自第三方控件.它正在实现 ApplicationCommands.SelectAll.但是我想要的行为略有不同.没有我可以覆盖的虚拟方法,当我注册一个类处理程序时,就像这样

Im deriving from a third party control. It is implementing ApplicationCommands.SelectAll. However the behaviour i want is slightly different. there is no virtual method i can override, and when i register a class handler, like so

     CommandManager.RegisterClassCommandBinding(typeof(MyDerivedControl), new CommandBinding(ApplicationCommands.SelectAll, new ExecutedRoutedEventHandler(OnExecutedSelectAll), new CanExecuteRoutedEventHandler(OnCanExecuteSelectAll)));

我的方法没有被调用.我派生的第三方控件是标记

My methods do not get called. The third party control i am deriving from is marking

e.Handled=true;

在它的命令处理程序中(我知道这是因为我已经看到了源代码,但我无法修改它)

in its command handlers ( i know this cause i have seen the source, but i cant modify it )

我能做什么?

推荐答案

你有三个选择:

1) 您可以注册您的 CommandBinding 来处理预览事件,而不是处理常规事件:

1) You can register your CommandBinding to handle preview events instead of or in addition to regular events:

CommandBinding cb = new CommandBinding(ApplicationCommands.SelectAll);
cb.PreviewCanExecute += OnCanExecuteSelectAll;
cb.PreviewExecuted += OnExecutedSelectAll;

但请注意 - 如果您已注册 PreviewExecuted,则在通过 CommandBinding 注册处理程序时,即使您将 e.Handled 显式设置为 false,已执行处理程序也永远不会运行.不过,对于 PreviewCanExecute/CanExecute 事件对,它确实可以正常工作.这就是 CommandBinding 类的实现方式.
因此,仅当您不希望基类命令处理程序运行时才使用 PreviewExecuted.

but beware - when registering handlers through CommandBinding if you have PreviewExecuted registered, the Executed handler will never run even if you explicitly set the e.Handled to false. It does work as expected for PreviewCanExecute/CanExecute pair of events though. This is the way CommandBinding class is implemented.
So use PreviewExecuted only if you do not want the base class command handler to run.

2) 或者,您可以直接通过 CommandManager 注册您的命令处理程序:

2) Alternatively you can register your command handlers through CommandManager directly:

CommandManager.AddPreviewCanExecuteHandler(this, OnCanExecuteSelectAll);
CommandManager.AddPreviewExecutedHandler(this, OnExecutedSelectAll);

虽然这不是一个类处理程序,所以您需要为每个实例都这样做.然后在您的处理程序中,您需要检查天气这是您感兴趣的命令(事件参数中有对该命令的引用).注意:您仍然需要注册 CommandBinding,但如果您只想直接在 CommandManager 上添加处理程序 - 您不需要使用该 Command Binding 注册任何处理程序.

This is not a class handler though so you'd need to do it for each instance. Then in your handler you'd need to check weather this is the command you're interested in (there is a reference to the command in event args). Note: you'll still have to register CommandBinding, but if you're going to only add handlers directly on CommandManager - you don't need to register any handlers with that Command Binding.

3) 或者你可以做一些 hack(不是真正的 hack):

3) Or you can do a bit of a hack(not really a hack):

this.AddHandler(CommandManager.CanExecuteEvent, new CanExecuteRoutedEventHandler(OnCanExecuteSelectAll), true);
this.AddHandler(CommandManager.ExecutedEvent, new ExecutedRoutedEventHandler(OnExecutedSelectAll), true);

通过这种方式,您可以注册命令事件处理程序,以便即使它们已经被处理,它们也会被执行.
与上述要点一样,您需要注册命令绑定才能触发 CommandManager 事件.
这与上面第 2 点中的内容几乎相同,但是当您调用 CommandManager.Add[四个事件之一]Handler 时,命令管理器会使用两个参数版本在控件上调用 AddHandler.

this way you register command event handlers so that they will be executed even if they were already handled.
As with the point above you'll need to register command binding in order for the CommandManager events to be fired.
This is almost the same stuff that is in the point 2 above, but when you call CommandManager.Add[one of the four events]Handler - the command manager calls AddHandler on the control using two argument version.

这篇关于WPF 两个命令处理程序,一个命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆