我在WPF4項目中使用MVVMLight,並且已經設置了一個ApplyCommand和一個UndoCommand,它們綁定到視圖上的按鈕。所有標準的東西,做了很多次。當用戶單擊按鈕時,將調用WCF服務方法,並更新局部變量。 UndoCommandCanExecute方法使用此局部變量來確定是否可以運行UndoCommand。MVVMLight命令CanExecute在異步調用後不會觸發
這工作正常,如果我同步WCF服務調用。但是,如果我使用異步調用,則CanExecute方法不會被觸發,因此撤消按鈕沒有正確啓用/禁用。
以下是兩種命令調用的視圖模型上的私有方法的簡化版本。在實際的代碼中,傳入參數,這些參數用於服務調用。
private void CallServiceMethod() {
IsBusy = true;
Task t = new Task(() => {
Thread.Sleep(2000); // would really call a WCF service
SetUndoMessage();
IsBusy = false;
});
t.Start();
}
如前所述,爲簡單起見,WCF服務調用已被調用Thread.Sleep所取代。 SetUndoMessage()方法設置UndoCommandCanExecute方法使用的局部變量。 IsBusy是綁定到視圖上的Telerik繁忙指示符的布爾,所以用戶可以看到發生了某些事情。
運行此操作時,撤消按鈕不能正確啓用或禁用,直到您單擊窗口上的某處。我在整個地方添加了Debug.WriteLine語句,並且可以看到在任務回調結束時未調用UndoCommandCanExecute方法。
我試圖在任務回調的末尾添加以下兩行,但它並沒有幫助...
CommandManager.InvalidateRequerySuggested();
UndoCommand.RaiseCanExecuteChanged();
如果我刪除了Thread.Sleep,然後正常工作,這聽起來就像是延遲就是問題所在。此方法在任務結束之前結束,因此UndoCommandCanExecute方法不會觸發。我不明白爲什麼它在我調用RaiseCanExecuteChanged方法或CommandManager時不會觸發。
我嘗試在我啓動線程後立即添加t.Wait(),但直到服務調用結束後才顯示忙指示,否定了整個目的。
任何任何想法如何解決這個問題?我想保持異步調用,因爲這使我可以使用忙碌指示符,這是整個大型應用程序的標準,並且還向用戶提供了一些反饋,指出發生了什麼。
我被卡住了使用C#4的方式,所以C#5的新異步功能對我來說不可用,即使它們能解決問題。
任何人能幫助我們嗎? –