2017-06-11 23 views
-2

私は単純なMVVMアプリケーションを持っています。一部のViewModelは非同期処理を実行します。非同期処理では、ステータスの更新について、および処理が完了したときにViewに通知する必要があります。WPFコマンドが継続タスクから実行されない

MVVMではViewへの直接呼び出しが制限されているので、私はコマンドを選択しました。タスクがメイン(UI)スレッドに同期されているにもかかわらず、継続タスクから呼び出された場合残念ながら、コマンドが実行されません:coomandは常に実行されます

public void DoAction() 
{ 
    //NOTE: command gets executed correctly 
    AppCommands.SomeCommand.Execute(null, null); 

    // run some task asynchronously 
    Task task = new Task(...); 

    task.ContinueWith(
     taskAntecedent => 
     { 
      //NOTE: command does not get executed at all! 
      AppCommands.SomeCommand.Execute(null, null); 
     }, 
     TaskScheduler.FromCurrentSynchronizationContext()); 

    task.Start(); 
} 

Executeメソッドは、(そのように適切なターゲット要素が含まれている場合WPFはビジュアルツリーを歩いてコマンドバインディングを見つけることができます)。 しかし、ビューが表示されないので、これはViewModelでは実行できません。 - いくつかのインターフェイスとしてコンストラクタを介してViewModelにするには、[View]を注入する

依存性の注入

他のいくつかのソリューションは、私が使用してみました。 1.これはViewModelに空のコンストラクタがなくなるため、ViewModelをXAMLで使用することはできません。私が空のコンストラクタを定義しても、develperは適切なViewを使用して適切なViewを注入することを忘れることがあります(Viewには、ユーザーによって置き換えられるViewModelがいくつかあります)。

ルーティングイベント - ViewModelには交換する必要があり、これは(MVVMのようではない)

ビューは、ビューのコード-behing必要とする新しいモデルに、旧モデルとrehookからイベントを外すために有することを意味しますサービス - 一部のビューはUserControlsであり、Windowsと異なり、Loaded、Unloadedイベントがないため、サービスを登録および登録解除するのに適していません。また、複数のコントロールを作成して、同じサービスを複数回登録すると、ViewsとViewModel間のバインディングは1:1になることはありません。

問題は単純です:

例えば方法View側またはユーザー/開発者が多くのコードを追加することなく、UserControlのViewModelからウィンドウを閉じますか?

私はバニラWPFでこれをやりたいのですが、アプリケーションは軽量で分かりやすい(できるだけ黒い魔法で)必要があるため、サードパーティのMVVMフレームワークは使用しないでください。

答えて

0

すなわちバックUIスレッド上で、コマンドを呼び出し、アクションを実行し、実際にTaskSchedulerをacceps ContinueWith方法の正しいオーバーロードを使用してみてください:

task.ContinueWith(
    taskAntecedent => 
    { 
     AppCommands.SomeCommand.Execute(null, null); 
    }, 
    System.Threading.CancellationToken.None, 
    TaskContinuationOptions.None, 
    TaskScheduler.FromCurrentSynchronizationContext()); 

これはいくつかのために動作しない場合理由は、問題のa Minimal, Complete, and Verifiable exampleを提供することをおすすめします。

+0

私は最後にCLRイベントを使用して、UserControlのLoaded、Unloaded、およびDataContextChangedハンドラでViewModelのイベントをフック/アンフックして問題を修正しました。サンプルをビルドするには2時間ほどかかりますが、残念ながら私は持っていません。私は後でこれに戻ることを願っています。 – Libor

関連する問題