ルート/メイン/シェル ビュー モデルが一種のDialogServiceインターフェイスを実装する場合、ダイアログを表示する必要がある他のすべてのビュー モデルは、ルート ビューモデルに依存することになります。場合によっては、これが望ましくない場合があります。たとえば、依存ループが発生する可能性がある場合などです:
DialogService (別名RootViewModel ) -> SomeViewModel - > RootViewModel。
この依存関係の連鎖を断ち切る (そして実際に逆にする) ためのより複雑なアプローチは次のとおりです。
- イベントを検出する動作を実装し、それをメイン ビューコンポーネント
Window.OnSourceInitialized
にアタッチします。Window
これは、ウィンドウ ハンドルが使用可能になったときに発生するイベントです。イベントが発生すると、動作は添付プロパティを介して渡されたハンドラーに通知します。
<my:WindowSourceBehavior InitListener="{Binding WindowListener}" />
public class WindowSourceBehavior : Behavior<Window>
{
// ...
// boilerplate code for IWindowListener InitListener dependency property
// ...
attachedWindow.SourceInitialized += (sender, evt) =>
{
// ...
InitListener.SourceInitialized(sender as Window);
}
}
- DialogServiceは、動作の要求に応じてハンドラー (またはインターフェイス) を公開します。
public class DialogService : IWindowListener
{
// ...
public void SourceInitialized(Window rootWindow) { /* ... */ }
}
- ルート ビュー モデルでは、(間接的に)依存関係として挿入されたDialogServiceを取得します。構築中に、ビューモデルにバインドされ
WindowListener
たプロパティ をDialogServiceハンドラ/インターフェースに設定します。
public MainViewModel(IWindowListener dialogServiceInDisguise)
{
WindowListener = dialogServiceInDisguise;
}
public IWindowListener WindowListener { get; private set; }
そうすることで、DialogService はルート Window を取得することができ、ダイアログを表示する必要があるビューモデルは、メイン ビューモデルへの (n 間接的な) 依存関係を作成しません。