2016-04-02 14 views
1

後のViewModelからアクションを実行します。私はこのような<code>ViewModel</code>持って右に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がCompletedイベントその上にコマンドが完了したときにトリガされ、別のViewModelにあるが(イベントは、トリガされたときに正しいログイン資格情報が使用されます)。 OtherVmは、何らかの理由で完了したイベントがトリガーされる別のVMです。

私はViewDataTemplateでレンダリングします。例えば:このウィンドウの

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

のDataContextはShowDialog前に、上記WelcomeWindowVmクラスに設定されています。

これはうまくいきます。 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 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 
} 

しかし、私は使用することはできませんが、中で待っています:私はこのようにそれを使用できるように

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

コンストラクターで、それに非同期メソッドを使用しても、ShowDialogを呼び出した後に別のクラスで呼び出す方法は、ShowDialogブロックですか?

私はasync voidを使用するとうまくいくと思います。しかし、私が聞いたことから、私がイベントハンドラでそれを使用しているのでなければ、避けるべきです。

async Taskメソッドを使用しますが、awaitを使用しない場合がありますか?

答えて

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

      }); 
     }); 
    } 
+0

おかげで、どのように非同期タスクの方法でそれを入れて、それを待っているではないでしょうか? 私はこのようなカスタムタスクに慣れていません。だから私は好奇心が強い。 –

+0

さて、そのメソッドの中に例外をスローすることはできません。内部をスローされた例外は観測されない可能性があるため、待機を無視することは通常推奨されません。あなたがこれを考慮に入れればそれはうまくいく(私は個人的には上記の方法を好むが)。 – Evk

+0

ContinueWithを使用せずに行ったことを行う方法はありますか?非同期を使用して待つだけですか? –

関連する問題