今回は「Windowがアクティブじゃない場合」についても考慮しています。
1.引数としてWindowを受け取る
コマンドのバインド時にCommandParameterにWindowを渡します。例)画面Load時のイベントにWindowを渡す場合
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction
Command="{Binding LoadedCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
ViewModelは
private void Loaded(Window window)
{
・・・
window.close()
}
のように画面を閉じることができます。
個人的にはViewModelでControl触るのはあまり好きじゃないなぁ
2.Closeメッセージを送る
こっちの方がMVVMぽいかな。Livetを使用しています。XAML側にCLOSEメッセージ受信用のトリガーを書きます
<i:Interaction.Triggers>
<l:InteractionMessageTrigger MessageKey="Close" Messenger="{Binding Messenger, Mode=OneWay}">
<l:WindowInteractionMessageAction InvokeActionOnlyWhenWindowIsActive="False"/>
</l:InteractionMessageTrigger>
</i:Interaction.Triggers>
private void Loaded(Window window)
{
・・・
Messenger.Raise(new WindowActionMessage(WindowAction.Close, "Close"));
}
※メッセージを使用する場合、Windowがアクティブではない場合、デフォルトでは処理が動きません。
通常の「閉じるボタンクリック」などでは問題ないですが「処理が終わったら画面を閉じる」のような処理の場合は、Windowが前面に出ていない可能性が結構あると思います。
InvokeActionOnlyWhenWindowIsActive="False"
を設定することで、アクティブ状態でなくてもメッセージを受け取ることができます。