我有ViewModel
这样:
public class WelcomeWindowVm : ViewModel
{
private ViewModel view;
public WelcomeWindowVm(){
this.View = new LoginVm() {
Completed += (o, e) => {
this.View = new OtherVm(e.User){
Completed += (o, e) =>; // and so on
}
}
};
}
public ViewModel View {
get {
return this.view;
}
set {
this.view = value;
this.OnPropertyChanged(nameof(this.View));
}
}
}
LoginVm
是另一个Viewmodel,当其上的命令完成时触发Completed事件(仅在使用正确的登录凭据时触发该事件)。 OtherVm
是另一个vm,无论出于何种原因,它都会触发完成的事件。
我使用View
渲染DataTemplate
。例如:
<Window.Resources>
<DataTemplate DataType="vm:LoginVm">
Textboes and buttons here
</DataTemplate>
<DataTemplate DataType="vm:OtherVm">
...
</DataTemplate>
</Window.Resources>
<ContentControl Content={Binding View} />
此窗口的DataContext在WelcomeWindowVm
之前设置为ShowDialog
级。
这很有效。使用ShowDialog显示窗口时,会显示LoginVm
。然后在完成LoginVm的任何任务时OtherVm
,依此类推。
现在我想把Completion的东西转换成Async / await模式。 LoginVm现在看起来像这样:
public LoginVm{
...
private TaskCompletionSource<User> taskCompletionSource = new TaskCompletionSource<User>();
...
// This is the Relay command handler
public async void Login()
{
// Code to check if credentials are correct
this.taskCompletionSource.SetResult(this.user);
// ...
}
public Task<User> Completion(){
return this.taskCompletionSource.Task;
}
}
而不是:
public LoginVm{
public event EventHandler<CustomArgs> Completed;
// This is the Relay command handler
public async void Login()
{
// Code to check if credentials are correct
OnCompleted(this.user);
// ...
}
}
所以我可以像这样使用它:
public WelcomeWindowVm(){
var loginVm = new LoginVm();
this.View = new LoginVm();
User user = await loginVm.Completion();
var otherVm = new OtherVm(user);
this.View = otherVm;
Whatever wev = await otherVm.Completion();
//And so on
}
但是我不能在构造函数中使用await,即使我使用异步方法,在调用ShowDialog
之后如何在ShowDialog
阻止之后在另一个类中调用它?< / p>
我认为使用async void
会有效。但是从我所听到的情况来看,除非我在事件处理程序中使用它,否则应该避免使用它。
也许使用async Task
方法而不是await
方法?
答案 0 :(得分:1)
你可以这样做:
public WelcomeWindowVm() {
var loginVm = new LoginVm();
this.View = loginVm;
loginVm.Completion().ContinueWith(loginCompleted =>
{
var otherVm = new OtherVm(loginCompleted.Result);
this.View = otherVm;
otherVm.Completion().ContinueWith(whateverCompleted =>
{
});
});
}