I have a ViewModel
like this:
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
is another Viewmodel whose Completed event is triggered when a Command on it is completed (The event is only triggered when correct login credentials are used). OtherVm
is another vm whose completed event is triggered for whatever reason.
I render the View
using a DataTemplate
. For example:
<Window.Resources>
<DataTemplate DataType="vm:LoginVm">
Textboes and buttons here
</DataTemplate>
<DataTemplate DataType="vm:OtherVm">
...
</DataTemplate>
</Window.Resources>
<ContentControl Content={Binding View} />
The DataContext of this window is set to WelcomeWindowVm
class above, before ShowDialog
.
This works well. When the Window is shown using ShowDialog, LoginVm
is shown. Then OtherVm
when whatever task of LoginVm is completed, and so on.
Now I thought of converting the Completion stuff to Async/await pattern. The LoginVm now looks like this:
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;
}
}
Instead of this:
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);
// ...
}
}
So that I can use it like this:
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
}
But I can't use await in a Constructor and even if I use an async Method for that, how will I call it in another class after calling ShowDialog
since ShowDialog
blocks?
I think using an async void
will work. But from what I have heard, it should be avoided unless I am using it in an event handler.
Maybe use an async Task
method but not await
it?
You can do it like this:
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 =>
{
});
});
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments