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