[英]Async CanExecute method using DelegateCommand in MVVM
[英]CanExecute Logic for DelegateCommand
更新:焦點變成了 MVVM 而不是實際問題,所以我正在更新它。
我在使用CanExecute
for DelegateCommand
遇到問題。 在我調用RaiseCanExecuteChanged
之前它不會更新,這是所需的行為嗎?
我在這里上傳了一個簡單的示例項目來重現這個問題: http : //dl.dropbox.com/u/39657172/DelegateCommandProblem.zip
問題是,我有兩個這樣的Buttons
。 一種是將Command
綁定到RelayCommand
實現,另一種是綁定到DelegateCommand
的 Prism 實現
<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
更新。 這是應該的方式嗎?
正如已經提到的,這是DelagateCommand
預期行為,而不是錯誤。 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));
如果你想堅持DelegateCommand
你可以使用ObservesCanExecute
:
DelegateSaveCommand = new DelegateCommand(Save, CanSaveDelegate).ObservesCanExecute(CanSaveDelegate);
請注意,也有ObservesProperty
可用,如果你正在使用您的CanExecute檢查屬性。 但隨后您的財產必須調用 NotifyPropertyChanged。
Prism 提供的 DelegateCommand 中有一個錯誤,它不會引發 CanExecute 事件。 我把頭靠在牆上一天,直到我深入到 Prism 框架提供的DelegateCommand
類。 我沒有代碼,但我可以稍后發布我的解決方案。
另一種方法是使用其他 RelayCommand 框架之一。
編輯
除了重新發布代碼之外,還有其他提供解決方案的 SO 問題:
並且 Kent B. 有一篇很好的文章: MVVM Infrastructure: DelegateCommand
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.