更新:焦点变成了MVVM,而不是实际的问题,所以我正在更新它。
我对CanExecute的DelegateCommand有个问题。在我调用RaiseCanExecuteChanged之前,它不会更新,这是想要的行为吗?

我上传了一个简单的示例项目,在这里再现了这个问题:http://dl.dropbox.com/u/39657172/DelegateCommandProblem.zip
问题是,我有两个这样的Buttons。一个是将Command绑定到RelayCommand实现,另一个绑定到DelegateCommand的棱镜实现。
<Button Command="{Binding DelegateSaveCommand}"/>
<Button Command="{Binding RelaySaveCommand}"/>ViewModel ICommands
DelegateSaveCommand = new DelegateCommand(Save, CanSaveDelegate);
RelaySaveCommand = new RelayCommand(param => Save(), param => CanSaveRelay);和CanExecute方法/谓词
public bool CanSaveDelegate()
{
return HasChanges;
}
public bool CanSaveRelay
{
get { return HasChanges; }
}两者都在使用属性HasChanges。当HasChanges被更新时,只有CanSaveRelay更新。这是命中注定的吗?
发布于 2011-09-08 19:55:36
正如前面提到的,这是DelagateCommand的预期行为,而不是bug。DelegateCommand不会自动引发CanExecuteChanged事件,您必须在适当时通过调用RaiseCanExecuteChanged来手动引发该事件。而RelayCommand则在CommandManager.RequerySuggested事件上对其进行中继。每当用户单击某个地方或按下按钮时,都会引发此事件。
对于不太方便或没有适当的位置调用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; }
}
}你可以这样使用它:
DelegateSaveCommand = new AutoCanExecuteCommandWrapper(new DelegateCommand(Save, CanSaveDelegate));发布于 2019-11-17 19:27:45
如果您想坚持使用DelegateCommand,可以使用ObservesCanExecute
DelegateSaveCommand = new DelegateCommand(Save, CanSaveDelegate).ObservesCanExecute(CanSaveDelegate);注意,如果您使用属性进行ObservesProperty检查,也可以使用CanExecute。但是,您的属性必须调用NotifyPropertyChanged。
发布于 2011-09-08 17:12:14
Prism提供的DelegateCommand中有一个bug,它不会引发CanExecute事件。我把头靠在墙上一天,直到深入到棱镜框架提供的DelegateCommand类中。我没有密码,但我可以在一段时间内发布我的决议。
另一种方法是使用其他RelayCommand框架之一。
编辑
与其重新发布代码,还有其他这样的问题可以提供解决方案:
肯特B.有一篇好文章:MVVM基础设施: DelegateCommand
https://stackoverflow.com/questions/7350845
复制相似问题