[英]Forcing Reevaluation on ICommand.CanExecute
In WPF XAML, I've got a Button
's Command
property working with an implementation of a class implementing ICommand
. 在WPF XAML中,我具有Button
的Command
属性,该属性与实现ICommand
的类的实现一起使用。
In this implementation, I don't have my CanExecuteChanged
event wired up to use CommandManager.RequerySuggested
- I want to have control over when CanExecute is called, and using this calls it way more often than necessary. 在此实现中,我没有连接CanExecuteChanged
事件以使用CommandManager.RequerySuggested
我想控制何时调用CanExecute,并且使用此调用的次数比必要的多。
The only other way I can get ICommand.CanExecute
to re-evaluate is to use something like: 我可以获得ICommand.CanExecute
进行重新评估的唯一其他方法是使用类似以下内容的方法:
public void InvokeCanExecute()
{
CanExecuteChanged.Invoke(this, new EventArgs());
}
In my class implementing the ICommand
. 在我的类中实现ICommand
。
This seems really nasty - am I missing something obvious? 这看起来真的很讨厌-我是否缺少明显的东西? I've tried invoking the re-evaluation using PropertyChanged
but that doesn't seem to work. 我尝试使用PropertyChanged
调用重新评估,但这似乎不起作用。
No, you are not really missing anything. 不,您并没有真正错过任何东西。 Here's a similar question that recommends the same approach you're taking: What is the actual task of CanExecuteChanged and CommandManager.RequerySuggested? 这是一个类似的问题,建议您采用相同的方法: CanExecuteChanged和CommandManager.RequerySuggested的实际任务是什么? . 。
You can make your method a little bit more robust though: 不过,您可以使方法更加健壮:
public void InvokeCanExecute()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, new EventArgs());
}
}
It's true that - if you don't want to use CommandManager.RequerySuggested
, which indeed might call CanExecute
more often than necessary - you need to explicitly invoke your own InvokeCanExecute
method in order to force the command to re-evaluate its CanExecute
condition. 的确是这样-如果您不想使用CommandManager.RequerySuggested
,它的确可能会比必要的调用CanExecute
更高-您需要显式调用自己的InvokeCanExecute
方法,以强制命令重新评估其CanExecute
条件。
However, in most cases the CanExecute
condition will depend on public (bindable) properties, meaning properties that raise the PropertyChanged
event to indicate that their value has changed - it is possible to hook into this event, in order to automatically call InvokeCanExecute
whenever one of the properties the command depends on has changed. 但是,在大多数情况下, CanExecute
条件将取决于公共(可绑定)属性,这意味着引发PropertyChanged
事件以指示其值已更改的PropertyChanged
-可以挂接到此事件,以便在InvokeCanExecute
任何一种情况下自动调用InvokeCanExecute
命令所依赖的属性已更改。 For an example of how to implement such a command, see this guy's blog post (if I'm not mistaken, this approach is implemented eg as part of the MVVM Light toolkit). 有关如何实现此命令的示例,请参见此人的博客文章 (如果我没记错的话,例如,作为MVVM Light工具包的一部分,实现了这种方法)。
Instantiating a command using this approach would look somewhat like the following: 使用这种方法实例化命令看起来类似于以下内容:
SaveCommand = new RelayCommand(() => { /* do some stuff; */ },
() => !string.IsNullOrEmpty(Name),
this, () => Name);
Since the command's CanExecute
condition (which checks whether Name
is empty) depends on the Name
property, it needs to be re-evaluated whenever Name
's content changes. 由于命令的CanExecute
条件(检查Name
是否为空)取决于Name
属性,因此只要Name
的内容更改,就需要重新评估该条件。 You simply pass a reference to the Name
property to the command's constructor, and InvokeCanExecute
will automatically be called whenever the value of Name
changes. 您只需将对Name
属性的引用传递给命令的构造函数,并且只要Name
的值更改, InvokeCanExecute
将自动被调用。
In theory, it is possible to go one step further and let the command itself check on which properties it depends - if you're interested in this approach, check out one of my blog articles , but note that this one heavily depends on reflection so it always depends on the detailed use-case whether this approach is feasible or not. 从理论上讲,可以更进一步,让命令本身检查依赖于哪些属性-如果您对此方法感兴趣,请参阅我的博客文章之一 ,但请注意,这一内容很大程度上取决于反射,因此这种方法是否可行始终取决于详细的用例。 A sample implementation of this solution is included in the MVVMbasics framework (disclaimer: published by me). 该解决方案的示例实现包含在MVVMbasics框架中 (免责声明:由我发布)。 In this case, you could reduce the command initialization code to: 在这种情况下,您可以将命令初始化代码减少为:
SaveCommand = CreateRelayCommand(() => { /* do some stuff; */ },
() => !string.IsNullOrEmpty(Name));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.