[英]Update ViewModel with async value, after/during call to ShowDialog
我正在創建一個模態 window,將它的DataContext
分配給我的視圖 model,然后調用ShowDialog
。
var vm = new MyViewModel(); // implements INotifyPropertyChanged
// populate vm properties here
var window = new MyWindow(); // inherits from System.Windows.Window
window.DataContext = vm;
window.ShowDialog();
但是,我想從async
方法的結果中填充視圖模型的屬性。
vm.Result = await provider.GetResultAsync();
我希望這些更改對 window 中的數據綁定屬性可見。
在調用ShowDialog
之前我不能這樣做,因為只有在結果可用后才會調用ShowDialog
。
在調用ShowDialog
后我不能這樣做,因為ShowDialog
會阻塞,直到 window 關閉。
我怎樣才能做到這一點?
將此代碼移入 MyWindow Class
然后在 window_loaded()
var vm = new MyViewModel(); // implements INotifyPropertyChanged
// populate vm properties here
this.DataContext = vm;
您可以通過多種方式做到這一點。 我推薦@WowoOt 的答案,因為視圖 model 必須是您嘗試使用的 window 的一部分。
另一種實現方式是在provider.GetResultAsync()
的調用中使用Task.ContinueWith方法,然后在回調中寫入vm.Result = task.Response
。 但是,這僅在您的視圖 model 實現INotifyPropertyChanged
時才有效。
這是此的代碼:
private void ButtonBase_OnClick(object sender, RoutedEventArgs e) {
// Supposed to open the window after clicking a button.
var vm = new MyViewModel();
var window = new MyWindow {
DataContext = vm
};
//vm.Result = await GetResultAsync();
_ = GetResultAsync().ContinueWith(x => vm.Result = x.Result);
window.ShowDialog();
static async Task<string> GetResultAsync() {
await Task.Delay(1000); // just to simulate a long process to recover the data.
return $"generated string: {new Random().Next(10)}";
}
}
我的示例視圖 model 實現了INotifyPropertyChanged
接口,以通知 XAML 框架有關其屬性的任何更改。
public class MyViewModel : INotifyPropertyChanged {
private string result;
public string Result {
get => this.result;
set {
this.result = value;
this.OnPropertyChanged();
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) {
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
感謝@Wowo Ot 的回答和@Marlonchonsky 的回答,我正在做以下事情:
var vm = new MyViewModel();
var window = new MyWindow();
window.DataContext = vm;
window.Loaded += async (s, e) => vm.Result = await provider.GetResultAsync();
window.ShowDialog();
它有效。
你可以做這樣的事情
vm.GetResultsTask = provider.GetResultsAsync();
然后,當您需要 MyWindow 中的結果時,您將await DataContext.GetResultsTask
來獲取它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.