ViewModelから他のViewを開く

概要

ViewModelから他のViewを開きたいとき、WinFormの場合だとFormのインスタンスを生成してShowDialog()を呼び出していたと思うが、MVVMパターンに準拠するとViewModelからViewに依存することになってしまう為、その方法は使用できない。

ではどうするかというとMessageパターンというものを使用して、ViewModel→Message→ViewというようにMessageを介すことでViewに依存関係を作らないようにするのだ。
これを普通に書くと結構なコード量になるが、LivetにはちゃんとMessageパターン用のクラスが用意されている。

やりたいこと

MainWindowからSubWindowを表示する

MainWindowViewModel.cs

MainWindowのViewModelからSubWindow表示用のメッセージを送る。
TransitionMessageコンストラクタの第一引数には表示するWindowのViewModelを渡し、第2引数にはメッセージキーを渡す。
メッセージキーはメッセージを受け取った時の振り分けに使用される。

using Livet;
using Livet.Messaging;

public void ShowSubWindow()
{
    Messenger.Raise(new TransitionMessage(new SubWindowViewModel(), "SubViewMessageKey"));
}

MainWindow.xaml

xamlにはメッセージを受け取り、SubViewを表示する旨を記述する。

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"

<i:Interaction.Triggers>
    <l:InteractionMessageTrigger MessageKey="SubViewMessageKey" Messenger="{Binding Messenger}">
        <l:TransitionInteractionMessageAction WindowType="{x:Type v:SubWindow}" Mode="Modal"/>
    </l:InteractionMessageTrigger>
</i:Interaction.Triggers>