CanExecute Logic for DelegateCommand
更新:焦点变成MVVM而不是实际的问题所以我正在更新它。
我遇到了CanExecute
for DelegateCommand
的问题。 在我调用RaiseCanExecuteChanged
之前它没有更新,这是否是所需的行为?
我在这里上传了一个简单的示例项目来重现这个问题: http : //dl.dropbox.com/u/39657172/DelegateCommandProblem.zip
问题是这个,我有两个像这样的Buttons
。 一个是绑定Command
到一个RelayCommand
实现,另一个是绑定到DelegateCommand
的Prism实现
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
。 这是它的意思吗?
正如已经提到的那样,这是DelagateCommand
预期行为,而不是bug。 DelegateCommand
不会自动引发CanExecuteChanged
事件,您必须在适当时通过调用RaiseCanExecuteChanged
手动引发该事件。 而RelayCommand
为CommandManager.RequerySuggested
事件中继。 每次用户点击某个位置或按下按钮时都会引发此事件。
对于不方便或没有适当的地方调用RaiseCanExecuteChanged
(就像在你的场景中你必须在模型上订阅PropertyChanged
事件等)我创建了以下简单的包装器,以确保CanExecute
方法的在CommandManager.RequerySuggested
事件上自动执行wrapped命令:
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));
Prism提供的DelegateCommand中存在一个错误,它不会引发CanExecute事件。 我把头撞到墙上一天,直到我进入Prism框架提供的DelegateCommand
类。 我没有代码,但我可以稍微发布我的分辨率。
另一种方法是使用其他RelayCommand框架之一。
编辑
而不是重新发布代码,还有其他提出解决方案的SO问题:
- WPF-Prism CanExecute方法未被调用
肯特B.有一篇好文章: MVVM基础设施:DelegateCommand