それにはいくつかのアプローチがあります。
ViewModelsプロジェクトで定義されたダイアログ/ナビゲーション/ウィンドウサービスインターフェイスを定義できます。ViewModelsがどのウィンドウを開きたいかをどのように表現するかを決定する必要があります。私は通常、一部のViewModelが実装するIDialogViewModelインターフェイスを使用し、ViewModelのインスタンスをサービスに渡しますが、列挙型、文字列など、必要に応じて使用できるため、実装は実際のウィンドウにマップできます。オープンしました。
例えば:
public interface IDialogService
{
bool? ShowDialog(object dialogViewModel);
}
新しいウィンドウを開きたいViewModelは、そのサービスのインスタンスを受け取り、それを使用してウィンドウを開く意図を表現します。ビュープロジェクトでは、ウィンドウを開く背後にある実際のロジックを使用して、サービスインターフェイスを実装するタイプを定義します。
例に従って:
public class DialogService : IDialogService
{
private Stack<Window> windowStack = new Stack<Window>();
public DialogService(Window root)
{
this.windowStack.Push(root);
}
public bool? ShowDialog(object dialogViewModel)
{
Window dialog = MapWindow(dialogViewModel);
dialog.DataContext = dialogViewModel;
dialog.Owner = this.windowStack.Peek();
this.windowStack.Push(dialog);
bool? result;
try
{
result = dialog.ShowDialog();
}
finally
{
this.windowStack.Pop();
}
return result;
}
}
メインプロジェクトは、ダイアログサービスを必要とするViewModelsにダイアログサービスを作成して挿入する責任があります。この例では、アプリはメインウィンドウを渡す新しいダイアログサービスインスタンスを作成します。
これを行うための同様のアプローチは、何らかの形式のメッセージングパターン(link1 link2)を使用すること です。さらに、単純なものが必要な場合は、ViewModelsがWindowsを開き、ビューにサブスクライブさせたいときにイベントを発生させることもできます。
編集
私がアプリで使用する完全なソリューションは、一般的にもう少し複雑ですが、基本的にはそれです。IDialogViewModelインターフェイスをDataContextとして実装するViewModelを期待するベースDialogWindowがあります。このインターフェイスは、accept / cancelコマンドやclosedイベントなど、ダイアログに期待されるいくつかの機能を抽象化するため、ViewModelからウィンドウを閉じることもできます。DialogWindowは、基本的にContentPresenterで構成され、ContentプロパティはDataContextにバインドされ、DataContextが変更されたときにcloseイベントをフックします(およびその他のいくつかのこと)。
各「ダイアログ」は、IDialogViewModelと関連するビュー(UserControl)で構成されます。それらをマップするために、アプリのリソースで暗黙のDataTemplatesを宣言するだけです。私が示したコードでは、唯一の違いは、メソッドMapWindowがなく、ウィンドウインスタンスが常にDialogWindowであるということです。
追加のトリックを使用して、ダイアログ間でレイアウト要素を再利用します。アプローチでは、それらをダイアログウィンドウに含めます(承認/キャンセルボタンなど)。DialogWindowをクリーンに保つのが好きです(「非ダイアログ」ダイアログにイベントを使用できるようにするため)。共通のインターフェイス要素を使用してContentControlのテンプレートを宣言し、View-ViewModelマッピングテンプレートを宣言するときに、「ダイアログテンプレート」を適用したContentControlでビューをラップします。次に、DialogWindowの「マスターテンプレート」を必要な数だけ持つことができます(たとえば、「ウィザードのような」ものなど)。