参考コード (Prism 7)
https://stackoverflow.com/a/61555337/9924249
https://github.com/HakamFostok/prism-boilerplate
通常のWindowの表示なのかDialogに限定した表示なのか、よくわからなかったのですが、新しいWindowの表示にも利用するようです。
ここでは、stackoverflowに書かれている回答をもとに考えてみます。
View
<StackPanel>
<Label Content="{Binding Title}"></Label>
<Button Content="Open Window" Command="{Binding OpenWindowCommand}"></Button>
</StackPanel>
OpenWindowCommandを実行しウインドウを開くことを期待できますが、どのウインドウを開くのかは分かりません。Viewは、他のViewを知らない、と言えるはずです。
ViewModel
private void OpenWindowCommandExecuted()
{
_dialogService.ShowWindowTest(CloseWindowEventHandler);
}
private void CloseWindowEventHandler(IDialogResult dialogResult)
{
}
ViewModelは、ボタンを押されたら、ShowWindowTestを実行します。メソッド名からみると、WindowTestViewをShowすることが期待されていますが、本当にそのウインドウを開くのかは分かりません。そのため、ViewModelは、WindowTestViewを知らない、と考えれば良いでしょうか?
メソッド名が、単に、ShowWindow、だったらと考えてみると、WindowTestViewを知らないことがはっきりします。
また、ウインドウが閉じられた後の処理(CloseWindowEventHandler)ができます。
Model
public static class DialogServiceExtensions
{
public static void ShowWindowTest(this IDialogService dialogService, Action<IDialogResult> action)
{
dialogService.ShowDialog(nameof(WindowTestView), new DialogParameters(), action);
}
}
WindowTestViewの名前を知っているのはModelです。public staticなので(IDialogService経由?)、どこからでも呼び出すことができますが、この例では、ViewModelから呼び出されています。
Prism 7のこの例では、Modelが確定したウインドウの名前を知って表示していることになると思います。
_dialogService
protected BaseViewModel()
{
_dialogService = ServiceLocator.Current.GetInstance<IDialogService>();
}
ちなみに、このViewModelで使われている_dialogServiceは、BaseViewModelにあります。
##Prism公式ドキュメントでは
https://prismlibrary.com/docs/wpf/dialog-service.html
Using the Dialog Service
では、VMに次のコードを書いているようです。
_dialogService.ShowDialog("NotificationDialog", new DialogParameters($"message={message}"), r =>
VMで、"NotificationDialog"というウインドウ名を指定しています。
Simplify your Application Dialog APIs
もっと簡単に利用できるように、DialogServiceExtensionsで、Showする方法が書かれています。
public static class DialogServiceExtensions
{
public static void ShowNotification(this IDialogService dialogService, string message, Action<IDialogResult> callBack)
{
dialogService.ShowDialog("NotificationDialog", new DialogParameters($"message={message}"), callBack, "notificationWindow");
}
}
この場合、ここで"NotificationDialog"のウインドウ名を指定しています。
まとめ
Prismでは、Dialog ServiceにViewの表示処理を、VMから渡してしまうようです。
また、VMでViewの名前をパラメータとして指定していても、MVVMとしてはOKというPrismの考えと思われます。名前の文字列なので、参照はしていない、という理屈なのでしょうか。
記事予定
- パターン1 Viewのコードビハインド
- パターン2 Commandパラメータ
- パターン3 Prism の Dialog Service(この記事)
- パターン4 引数を渡す(予定)