はじめに
Prism7.2 から IDialogService が実装されてダイアログ表示がいい感じになった。
しかし、通知用や確認用などの汎用的なダイアログをプロジェクトごとにいちいち作るのも面倒くさい。
なので IDialogService で呼び出せる一般的に使いそうなダイアログを作ってライブラリ化して nuget に公開した。
できたもの
機能
通知ダイアログ
確認ダイアログ
ファイル選択ダイアログ
フォルダ選択ダイアログ
ファイル保存ダイアログ
アイコンなどのカスタマイズ
Window のカスタマイズ
使い方
IDialogService 自体の使い方は公式ドキュメントを読むのが早い。
ここでは Prism.CommonDialogPack の使い方だけを記述する。
インストール
nuget に公開したのでパッケージマネージャーコンソールから簡単にインストールできる。
Install-Package PrismCommonDialogPack
登録
まずは App でモジュールとサービスの登録を行う。
public partial class App
{
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
base.ConfigureModuleCatalog(moduleCatalog);
moduleCatalog.AddModule<CommonDialogPackModule>();
}
protected override void RegisterRequiredTypes(IContainerRegistry containerRegistry)
{
base.RegisterRequiredTypes(containerRegistry);
containerRegistry.RegisterSingleton<Prism.Services.Dialogs.IDialogService, StyleableDialogService>();
}
}
Prism が提供してくれている DialogService は Window の Style を DialogWindow を介してセットしているが、Window に単に代入するような実装になっているのでライブラリにした時に呼び出し側から Style を指定することができない。
Prism.CommonDialogPack では Dialog の呼び出し側から Style を指定できるようにするため、DialogService を継承したStyleableDialogService を作っている。
違いはConfigureDialogWindowContent
メソッドだけで、ViewModel が IStyleableDialogAware だった場合は Style をバインディングするようにしている。
また、WindowStartupLocation もここで設定している。
IStyleableDialogAware は IDialogAware に WindowStyle や Height, Width などを追加したインターフェイスで、ダイアログとして表示する View の ViewModel に実装することでライブラリの呼び出し側からの Style 指定などを可能にしている。
RegisterRequiredTypes
では標準の IDialogService の実態を DialogService ではなく StyleableDialogServiceにするようにコンテナに登録している。
呼び出し
呼び出しは IDialogService を介して行う。
private void ShowNotificationDialog(IDialogService dialogService)
{
var param = new DialogParameters
{
{ DialogParameterNames.Title, "myNotification" }
};
dialogService.ShowDialog(DialogNames.Notification, param, res =>
{
});
}
こんな感じで通常の DialogService と変わらない。
呼び出せるダイアログの名前は DialogNamesに、
指定できるパラメーターの名前はDialogParameterNamesに、
受け取れるパラメーターの名前はDialogResultParameterNamesに定義してある。
パラメーターの受け取りは FileSelectDialog、FolderSelectDialog、FileSaveDialog でのみ可能で、コールバックで受け取れる IDialogResult の Parameters プロパティから取得する。
各ダイアログで指定できるパラメーターは以下の通り
共通
名前 | 型 | 内容 |
---|---|---|
Title | string | Window のタイトル |
Width | double | Window の幅 |
Height | double | Window の高さ |
ContentWidth | double | Content の幅 |
ContentHeight | double | Content の高さ |
WindowStyle | System.Windows.Style | Window の Style |
StartupLocation | System.Windows.StartupLocation | Window の表示位置 |
ResizeMode | System.Windows.ResizeMode | Window のリサイズ可否と方法 |
SizeToContent | System.Windows.SizeToContent | コンテンツのサイズに Window を合わせるか |
※SizeToContent を Manual 以外にした場合は Width, Height を指定していても指定した SizeToContent が優先されるので注意
NotificationDialog
名前 | 型 | 内容 |
---|---|---|
Message | string | 表示するメッセージ |
ButtonText | sgring | ボタンのテキスト |
ConfirmationDialog
名前 | 型 | 内容 |
---|---|---|
Message | string | 表示するメッセージ |
OKButtonText | sgring | OK ボタンのテキスト |
CancelButtonText | sgring | Cancel ボタンのテキスト |
FileSelectDialog
名前 | 型 | 内容 |
---|---|---|
ExplorerIcons | Prism.CommonDialogPack.ExplorerIcons | アイコン |
FileNamePrefixText | string | ファイル名の前に表示されるテキスト |
SelectButtonText | string | 選択ボタンのテキスト |
CancelButtonText | string | Cancel ボタンのテキスト |
Filters | IEnumerable<Prism.CommonDialogPack.FileFilter> | 表示するファイルのフィルター |
TextResource | Prism.CommonDialogPack.ExplorerBaseTextResource | ExplorerBase に表示するテキスト |
CanMultiSelect | bool | 複数選択可能かどうか |
RootFolders | IEnumerable<string> | ルートにするフォルダーのパス |
FolderSelectDialog
名前 | 型 | 内容 |
---|---|---|
ExplorerIcons | Prism.CommonDialogPack.ExplorerIcons | アイコン |
FolderNamePrefixText | string | フォルダー名の前に表示されるテキスト |
SelectButtonText | string | 選択ボタンのテキスト |
CancelButtonText | string | Cancel ボタンのテキスト |
TextResource | Prism.CommonDialogPack.ExplorerBaseTextResource | ExplorerBase に表示するテキスト |
CanMultiSelect | bool | 複数選択可能かどうか |
RootFolders | IEnumerable<string> | ルートにするフォルダーのパス |
FileSaveDialog
名前 | 型 | 内容 |
---|---|---|
ExplorerIcons | Prism.CommonDialogPack.ExplorerIcons | アイコン |
FileNamePrefixText | string | ファイル名の前に表示されるテキスト |
FileTypePrefixText | string | ファイルの種類の前に表示されるテキスト |
SaveButtonText | string | 保存ボタンのテキスト |
CancelButtonText | string | Cancel ボタンのテキスト |
DefaultSaveFileName | string | 初期ファイル名 |
Filters | IEnumerable<Prism.CommonDialogPack.FileFilter> | 表示するファイルのフィルター |
TextResource | Prism.CommonDialogPack.ExplorerBaseTextResource | ExplorerBase に表示するテキスト |
CanMultiSelect | bool | 複数選択可能かどうか |
RootFolders | IEnumerable<string> | ルートにするフォルダーのパス |
OverwriteConfirmationTitle | string | 上書き確認ダイアログのタイトル |
OverwriteConfirmationMessageFunc | Func<string, string> | 上書き確認ダイアログのメッセージ生成関数 |
OverwriteConfirmationOKButtonText | string | 上書き確認ダイアログの OK ボタンのテキスト |
OverwriteConfirmationCancelButtonText | string | 上書き確認ダイアログの Cancel ボタンのテキスト |
※OverwriteConfirmationMessageFunc
にはファイルのフルパスが渡される。これを指定することで上書き確認ダイアログで表示するメッセージを呼び出し側から書き換えることが可能。
その他のクラスについて
ExplorerIcons
パラメーターで渡せば FileSelectDialog, FolderSelectDialog, FileSaveDialog のアイコンをカスタムできる。
FileFilter
パラメーターで渡せば FileSelectDialog, FileSaveDialog で表示するファイルの拡張子にフィルターをかけることができる。
new FileFilter("All Files (*.*)"),
new FileFilter("Text File (*.txt; *.csv)", new[] { ".txt", ".csv" }),
new FileFilter("Excel File (*.xlsx; *.xlsm; *.xls)", ".xlsx", ".xlsm", ".xls"),
使い方はこんな感じで、Text プロパティの文字列が ComboBox に表示され、Extensions プロパティの文字列が実際にフィルターする拡張子となる。
Extensions が空だとフィルターしない。
FileSaveDialog の場合は保存するファイルの拡張子を指定する意図で使用するため、Extensions を複数指定しても最初のものだけフィルターされる。
ExplorerBaseTextResource
パラメーターで渡せば ExplorerBase の各テキストをカスタムできる。
DialogServiceExtensions
ダイアログの呼び出しを簡素化した拡張メソッドを定義したクラス。
dialogService.ShowNotification("Notification", "Notification", res => Console.WriteLine(res.Result));
Window のカスタマイズ
これ自体は IDialogService の機能なので、やり方も同じ。
ダイアログに使いたい Window にコードビハインドでIDialogWindow
を実装する
IDialogWindow
はIDialogResult
プロパティを持っているだけ
public partial class MyMetroWindow : MetroWindow, IDialogWindow
{
public IDialogResult Result { get; set; }
public MyMetroWindow()
{
InitializeComponent();
}
}
あとはRegisterDialogWindow
でコンテナに登録する
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterDialogWindow<MyMetroWindow>();
}
おわりに
Prism.CommonDialogPack にはサンプルもつけているので、詳細はそっちを見ればわかるかも。