WPFのプログラムをMVVMパターンで記述する際に、ダイアログを用いたユーザーとの対話をどう記述するかについてさまざまなアプローチがある。そのうちの一つに、PrismのInteraction Requestを用いる方法がある。
この方法でダイアログを表示するときの問題は、MahAppsのようなサードパーティのウィンドウを使っているときに、普通のウィンドウが使われてしまうため外観を統一できなくなることだ。
これを避けるには、まずPrismのPopupWindowAction
を継承してサブクラスを作り、CreateWindow()
をオーバーライドしてMahAppsのMetroWindow
を生成する。ただし、CreateWindow()
はPrism 6.0以降にしかないので注意してほしい。
using System.Windows;
using MahApps.Metro.Controls;
using Prism.Interactivity;
namespace Sample
{
internal class MetroPopupWindowAction : PopupWindowAction
{
protected override Window CreateWindow()
{
return new MetroWindow
{
Style = new Style(),
SizeToContent = SizeToContent.WidthAndHeight
};
}
}
}
どのダイアログにも共通するプロパティはここで指定しておく。Style
には空のスタイルを設定しておかないと、なぜかダイアログを表示するタイミングでArgumentNullException
が出てしまう。
このMetroPopupWindowAction
を、InteractionRequestTrigger
のアクションとして指定する。表示するダイアログのスタイルはWindowStyle
で指定する。ただし、TargetType
でWindow
以外のクラスを指定できるのは、Prism 6.1からである。
<prism:InteractionRequestTrigger SourceObject="{Binding ConfirmationRequest, Mode=OneWay}">
<local:MetroPopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
<local:MetroPopupWindowAction.WindowContent>
<local:ConfirmDialog/>
</local:MetroPopupWindowAction.WindowContent>
<local:MetroPopupWindowAction.WindowStyle>
<Style TargetType="controls:MetroWindow">
<Setter Property="ResizeMode" Value="NoResize"/>
<Setter Property="ShowInTaskbar" Value="False"/>
</Style>
</local:MetroPopupWindowAction.WindowStyle>
</local:MetroPopupWindowAction>
</prism:InteractionRequestTrigger>
Prism 6.0より前でも、PopupWindowAction
のソースコードを参考にGetWindow()
をオーバーライドする形でサブクラスを定義すれば、同じことができるはずだ。