好吧,讓我試着解釋一下。如何強制更新MVVM中的UI?
我有一個應用程序,我可以觸發某種掃描過程。這個掃描過程啓動(只是一個數字)10個背景的工作人員做些事情。後(再次,只是一個數字)5秒我想
- 殺死所有的後臺工作人員(我使用CancelAsync爲)
- 做一些計算與我從所有這些 的獲得了數據
- 更新UI,使得顯示的數據,並實現一些按鈕(這些按鈕通過
ViewModel
命令約束稱爲PerformUpdateCommand
和他們的IsPerformUpdateAllowed
一個CanExecute
屬性。當我的任務完成IsPerformUpdateAllowed
依賴屬性設置。
我想我會做:
- 觸發背景工人後,使用5秒的間隔定時器調度。
- 當
DispatcherTimer
「ticks」我計算數據並將屬性IsPerformUpdateAllowed
設置爲true或false。
這只是基本上按預期工作(用戶界面保持響應,...)只是一個小問題:用戶界面沒有被更新(按鈕未啓用)。只要我將窗口放入背景並返回到前景中,該命令即會啓用,並且IsPerformUpdateAllowed
屬性也將設置爲true。另外,按下按鈕後(禁用狀態),它將被啓用。
所以,雖然我正確設置了依賴項屬性,但UI並未對此更改做出反應。
有人知道爲什麼嗎?有趣的是,我還在用戶界面中設置了一些文本到一個標籤 - 這個文本被正確更新。只是告訴命令CanExecute
的屬性不會觸發UI更新。
定時器初始化代碼。
_scanTimer = new DispatcherTimer();
_scanTimer.Interval = new TimeSpan(0, 0, 0, 3);
_scanTimer.Tick += delegate
{
// After the timer has elapsed (some time passed), cancel all scans and update the result
_scanTimer.Stop();
UpdateScanResults();
CancelNormalScans(false);
};
_scanTimer.Start();
代碼的命令是如何結合到WPF元件(按鈕實際上是一個超鏈接):
<Label Grid.Row="1" Grid.Column="1">
<Hyperlink Command="{Binding ReadSettingsCommand}">
<TextBlock Text="{Binding Source={StaticResource Loc}, Path=Labels.ReadSettings}"></TextBlock>
</Hyperlink>
</Label>
下面是命令
public RelayCommand ReadSettingsCommand
{
get
{
return _readSettingsCommand
?? (_readSettingsCommand = new RelayCommand(ExecuteReadSettings,() => IsScannedDeviceAvailable && !IsUpdateInProgress));
}
}
的代碼是代碼實際上依賴於兩個依賴項屬性IsScannedDeviceAvailable AND NOT IsUpdateInProgress。兩者都是依賴屬性。
更新:我剛剛讀到綁定到CanExecute屬性只是一次。如果你想讓它重新生效,你需要在命令上調用RaiseCanExecuteChanged。這可以起作用,但它有點麻煩,因爲現在我需要在兩個屬性中的一個發生更改時手動調用它。其實我想讓它自動處理。關於如何更輕鬆地完成這些任何想法? CanExecute和屬性之間是否存在某種單向綁定的方法?
什麼是您的IsPerformUpdateAllowed DependencyProperty? – markmnl
您的ICommands不會引發CanExercuteChanged事件。 – Aron
@Aron:有沒有比手動調用RaiseCanExecuteChanged更好的方法? –