[英]CanExecute Logic for DelegateCommand
Update: The focus became MVVM instead of the actual question so I'm updating it.更新:焦点变成了 MVVM 而不是实际问题,所以我正在更新它。
I'm having a problem with CanExecute
for DelegateCommand
.我在使用
CanExecute
for DelegateCommand
遇到问题。 It doesn't update before I call RaiseCanExecuteChanged
, is this the desired behavior?在我调用
RaiseCanExecuteChanged
之前它不会更新,这是所需的行为吗?
I uploaded a simple sample project reproducing this problem here : http://dl.dropbox.com/u/39657172/DelegateCommandProblem.zip我在这里上传了一个简单的示例项目来重现这个问题: http : //dl.dropbox.com/u/39657172/DelegateCommandProblem.zip
The problem is this, I have two Buttons
like this.问题是,我有两个这样的
Buttons
。 One is Binding Command
to a RelayCommand
implementation and the other is binding to the Prism implementation of DelegateCommand
一种是将
Command
绑定到RelayCommand
实现,另一种是绑定到DelegateCommand
的 Prism 实现
<Button Command="{Binding DelegateSaveCommand}"/>
<Button Command="{Binding RelaySaveCommand}"/>
The ViewModel ICommands
ViewModel
ICommands
DelegateSaveCommand = new DelegateCommand(Save, CanSaveDelegate);
RelaySaveCommand = new RelayCommand(param => Save(), param => CanSaveRelay);
and the CanExecute
method/predicate和
CanExecute
方法/谓词
public bool CanSaveDelegate()
{
return HasChanges;
}
public bool CanSaveRelay
{
get { return HasChanges; }
}
Both are using the property HasChanges
.两者都使用属性
HasChanges
。 When HasChanges
is updated, only the CanSaveRelay
updates.当
HasChanges
更新时,只有CanSaveRelay
更新。 Is this the way it's meant to be?这是应该的方式吗?
As it already was mentioned, this is intended behavior of DelagateCommand
, not a bug.正如已经提到的,这是
DelagateCommand
预期行为,而不是错误。 DelegateCommand
doesn't raise CanExecuteChanged
event automatically, you have to raise that event manually by calling RaiseCanExecuteChanged
when appropriate. DelegateCommand
不会自动引发CanExecuteChanged
事件,您必须在适当的时候通过调用RaiseCanExecuteChanged
手动引发该事件。 Whereas RelayCommand
relays on CommandManager.RequerySuggested
event for that.而
RelayCommand
在CommandManager.RequerySuggested
事件上中继。 This event is raised every time the user clicks somewhere or presses a button.每次用户单击某处或按下按钮时都会引发此事件。
For situations when it is not very convenient or there is no appropriate place for calling RaiseCanExecuteChanged
(like in your scenario you have to subscribe to PropertyChanged
event on the model, etc) I have created the following simple wrapper that ensures that the CanExecute
method of the wrapped command is executed automatically on CommandManager.RequerySuggested
event:因为当它是不是很方便,或者没有合适的地方调用情况
RaiseCanExecuteChanged
(如在你的情况下,你必须订阅PropertyChanged
事件的模型等),我已经创建了如下简单的包装,确保CanExecute
的方法包装命令在CommandManager.RequerySuggested
事件上自动执行:
public class AutoCanExecuteCommandWrapper : ICommand
{
public ICommand WrappedCommand { get; private set; }
public AutoCanExecuteCommandWrapper(ICommand wrappedCommand)
{
if (wrappedCommand == null)
{
throw new ArgumentNullException("wrappedCommand");
}
WrappedCommand = wrappedCommand;
}
public void Execute(object parameter)
{
WrappedCommand.Execute(parameter);
}
public bool CanExecute(object parameter)
{
return WrappedCommand.CanExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
You can use it like this:你可以这样使用它:
DelegateSaveCommand = new AutoCanExecuteCommandWrapper(new DelegateCommand(Save, CanSaveDelegate));
If you want to stick to DelegateCommand
you can use ObservesCanExecute
:如果你想坚持
DelegateCommand
你可以使用ObservesCanExecute
:
DelegateSaveCommand = new DelegateCommand(Save, CanSaveDelegate).ObservesCanExecute(CanSaveDelegate);
Note that there is also ObservesProperty
available if you are using a property for your CanExecute check.请注意,也有
ObservesProperty
可用,如果你正在使用您的CanExecute检查属性。 But then your property has to call NotifyPropertyChanged.但随后您的财产必须调用 NotifyPropertyChanged。
There is a bug in the DelegateCommand provided by Prism which doesn't raise the CanExecute event. Prism 提供的 DelegateCommand 中有一个错误,它不会引发 CanExecute 事件。 I beat my head against the wall for a day until I dove into the
DelegateCommand
class provided by the Prism framework.我把头靠在墙上一天,直到我深入到 Prism 框架提供的
DelegateCommand
类。 I don't have the code with me, but I can post my resolution in a bit.我没有代码,但我可以稍后发布我的解决方案。
The alternative is to use one of the other RelayCommand frameworks out there.另一种方法是使用其他 RelayCommand 框架之一。
Edit编辑
Rather than reposting the code, there are other SO questions that provide resolutions:除了重新发布代码之外,还有其他提供解决方案的 SO 问题:
And Kent B. has a good article: MVVM Infrastructure: DelegateCommand并且 Kent B. 有一篇很好的文章: MVVM Infrastructure: DelegateCommand
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.