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

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

问题描述

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

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

我的方法不被调用。我得出的第三方控制正在标记



e.Handled = true;



在命令处理程序(我知道这是因为我已经看到源,但我不能修改它)



我能做什么?

解决方案

您有三个选项:



您的CommandBinding来处理预览事件,而不是常规事件或除了常规事件之外:

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

但是要注意 - 通过CommandBinding注册处理程序时,如果你已经注册了PreviewExecuted,Executed处理程序永远不会运行如果你显式设置e.Handled为false。它工作作为预期的PreviewCanExecute / CanExecute对事件。这是CommandBinding类的实现方式。

因此,只有在不想运行基类命令处理程序时才使用PreviewExecuted。



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

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

这不是一个类处理程序,所以你需要为每个实例。然后在你的处理程序中,你需要检查weather这是你感兴趣的命令(在事件args中有一个对命令的引用)。注意:你仍然需要注册CommandBinding,但是如果你只是直接在CommandManager中添加处理程序 - 你不需要注册任何处理程序与命令绑定。



3)或者你可以做一点黑客(不是真正的黑客):

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

这样注册命令事件处理程序,以便即使已经处理它们也将被执行。 br>
与上面的内容一样,您需要注册命令绑定,以便启动CommandManager事件。

这几乎是上面第2点中的内容,但是当你调用CommandManager.Add [四个事件之一] Handler - 命令管理器使用两个参数版本在控件上调用AddHandler。


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 )

What can i do?

解决方案

You have three options:

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;

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) Alternatively you can register your command handlers through CommandManager directly:

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

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) 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);

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天全站免登陆