2016-04-02 13 views
1

sonra ViewModel gelen bir eylem yapın:Böyle bir <code>ViewModel</code> var sağ ShowDialog

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 Tamamlanan olay üzerinde bir komut tamamlandığında tetiklenir başka ViewModel olan (olay sadece tetiklendiğinde Doğru giriş kimlik bilgileri kullanılır). OtherVm, tamamlanmış olayı herhangi bir nedenle tetiklenen başka bir vm'dir.

DataTemplate kullanarak View'u oluşturuyorum. Bu pencerenin DataContext ShowDialog önce yukarıda WelcomeWindowVm sınıfına ayarlanır

<Window.Resources> 
    <DataTemplate DataType="vm:LoginVm"> 
     Textboes and buttons here 
    </DataTemplate> 
    <DataTemplate DataType="vm:OtherVm"> 
     ... 
    </DataTemplate> 
</Window.Resources> 
<ContentControl Content={Binding View} /> 

: Örneğin.

Bu iyi çalışıyor. Pencere ShowDialog kullanılarak gösterildiğinde, LoginVm gösterilmektedir. Daha sonra LoginVm'nin görevi ne zaman tamamlanırsa, OtherVm.

Artık Tamamlama öğelerini Async/await düzenine dönüştürmeyi düşündüm. LoginVm şimdi şöyle görünür:

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; 
    } 
} 

Bunun yerine:

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 
} 

Ama kullanamayan bir de bekliyor: Böyle kullanabilirsiniz Böylece

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); 
     // ... 
    } 
} 

Yapıcı ve bunun için bir uyumsuzluk Metodu kullansam bile, ShowDialog bloklarından beri ShowDialog'u aradıktan sonra başka bir sınıfta nasıl arayacağım?

Bir async void kullanacağını düşünüyorum. Ama duyduğum şeyden, bir olay işleyicisinde kullanmıyorsam kaçınılmalıdır.

Belki bir async Task yöntemini kullanın, ancak await değil mi?

cevap

1

Böyle yapabilirsiniz:

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 => 
      { 

      }); 
     }); 
    } 
+0

Teşekkür, nasıl bir zaman uyumsuz Görev yönteminde koyarak ve onu bekleyen değil dersiniz? Bunun gibi özel görevlere çok aşina değilim. Bu yüzden merak ediyorum. –

+0

Peki, bu yöntemin içinde istisnaların atılamayacağından emin olmalısınız. Beklemeyi ihmal etmek genellikle tavsiye edilmez, çünkü içeriye atılan istisnalar gözlemlenmemiş olabilir. Eğer bunu hesaba katarsanız, o zaman sorun yok (yine de yukarıdaki yöntemi tercih ediyorum). – Evk

+0

ContinueWith'i kullanmadan yaptığınız şeyi yapmanın bir yolu var mı? Async kullanımı sadece beklemede mi? –