在WPF XAML中,我有一个Button
的{{1}}属性正在使用实现Command
的类的实现。
在此实现中,我不将ICommand
事件连接起来使用CanExecuteChanged
- 我希望能够控制何时调用CanExecute,并使用此功能不必要地调用它。
我可以让CommandManager.RequerySuggested
重新评估的另一种方法是使用类似的东西:
ICommand.CanExecute
在我的班级中实施public void InvokeCanExecute()
{
CanExecuteChanged.Invoke(this, new EventArgs());
}
。
这看起来真的很讨厌 - 我错过了一些明显的东西吗?我尝试使用ICommand
调用重新评估,但这似乎不起作用。
答案 0 :(得分:1)
不,你真的没有遗漏任何东西。这是一个类似的问题,建议您采用相同的方法:What is the actual task of CanExecuteChanged and CommandManager.RequerySuggested?。
您可以使您的方法更加健壮:
public void InvokeCanExecute()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, new EventArgs());
}
}
答案 1 :(得分:1)
确实如此 - 如果您不想使用CommandManager.RequerySuggested
,确实可能更频繁地调用CanExecute
- 您需要按顺序显式调用自己的InvokeCanExecute
方法强制命令重新评估其CanExecute
条件。
但是,在大多数情况下,CanExecute
条件将取决于公共(可绑定)属性,这意味着引发PropertyChanged
事件以指示其值已更改的属性 - 可以挂钩event,以便在命令所依赖的某个属性发生更改时自动调用InvokeCanExecute
。有关如何实现此类命令的示例,请参阅this guy's blog post(如果我没有记错,这种方法是作为 MVVM Light 工具包的一部分实现的。)
使用此方法实例化命令看起来如下所示:
SaveCommand = new RelayCommand(() => { /* do some stuff; */ },
() => !string.IsNullOrEmpty(Name),
this, () => Name);
由于命令的CanExecute
条件(检查Name
是否为空)取决于Name
属性,因此只要Name
的内容需要重新评估它变化。您只需将对Name
属性的引用传递给命令的构造函数,只要InvokeCanExecute
的值发生更改,就会自动调用Name
。
理论上,可以更进一步,让命令本身检查它所依赖的属性 - 如果你对这种方法感兴趣,请查看 one of my blog articles,但请注意,这一点在很大程度上取决于反射,所以它总是取决于详细的用例 - 这种方法是否可行。此解决方案的示例实现包含在the MVVMbasics framework中(免责声明:由我发布)。在这种情况下,您可以将命令初始化代码减少为:
SaveCommand = CreateRelayCommand(() => { /* do some stuff; */ },
() => !string.IsNullOrEmpty(Name));