Prism.Wpf(MVVM)で気軽にMessageBoxをShowしたい
結論
LivetCask.Messagingが便利でした。
はじめに
Prism.Wpf(MVVM)で確認ダイアログを表示する方法として以下が考えられます。
- ViewModelでSystem.Windows.MessageBox.Showする
- PrismのInteractionRequestでConfirmationを使用する
- PrismのIDialogServiceを使用する
- Messagerパターンで自作する
- etc
1.はViewModelで画面操作をするとは何事かとMVVM原理主義者に怒られるのであまりできません。
2.はSystem.Window.MessageBoxではないのですがPrismで既定で画面を用意してくれていましたが、IDialogServiceの導入により廃止予定です。
3.は自分でWindowベースで画面を用意しないといけません。
特に画面を装飾する必要がなく、ただただ見慣れた確認ダイアログを出したいと思っても面倒くさいのです。
LivetCask.Messagingが便利
で存在に気付けました。ありがとうございます。
System.Window.MessageBoxをMessengerパターンで発火してくれるAction等々ありましたのでご紹介です。
詳細はGithub参照願います。
環境
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
<LangVersion>8.0</LangVersion>
<PackageReference Include="LivetCask.Messaging" Version="3.2.1" />
<PackageReference Include="prism.Unity" Version="7.2.0.1422" />
<PackageReference Include="ReactiveProperty" Version="6.2.0" />
<PackageReference Include="Unity" Version="5.11.3" />
xmlns:prism="http://prismlibrary.com/"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
prism:ViewModelLocator.AutoWireViewModel="True"
Action列挙
クラス名 | 説明(抜粋) |
---|---|
ConfirmationDialogInteractionMessageAction | 確認ダイアログを表示するアクションです。ConfirmationMessageに対応します。 |
InformationDialogInteractionMessageAction | 情報ダイアログを表示するアクションです。InformationMessageに対応します。 |
OpenFileDialogInteractionMessageAction | 「ファイルを開く」ダイアログを表示するアクションです。OpeningFileSelectionMessageに対応します。 |
SaveFileDialogInteractionMessageAction | 「ファイルを保存する」ダイアログを表示するアクションです。SavingFileSelectionMessageに対応します。 |
WindowInteractionMessageAction | Windowの最小化・最大化・閉じるを行うアクションです。WindowActionMessageに対応します。 |
etc |
ConfirmationDialogInteractionMessageAction
xam例
<Button Content="Livet Messenger: View Raise">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<l:ConfirmationDialogInteractionMessageAction>
<l:DirectInteractionMessage CallbackMethodName="ViewMessager" CallbackMethodTarget="{Binding}">
<l:ConfirmationMessage Caption="title" Text="View Raise" />
</l:DirectInteractionMessage>
</l:ConfirmationDialogInteractionMessageAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button Content="Livet Messenger: View Raise">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<l:ConfirmationDialogInteractionMessageAction>
<l:DirectInteractionMessage CallbackMethodName="ViewMessager" CallbackMethodTarget="{Binding}">
<l:ConfirmationMessage Caption="title" Text="View Raise" />
</l:DirectInteractionMessage>
</l:ConfirmationDialogInteractionMessageAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
ViewModelを介さずに発火できます。戻り値を受け取る際はCallbackMethodNameとCallbackMethodTargetを指定します。
public void ViewMessager(ConfirmationMessage message)
{
OutputMessage.Value = $"{DateTime.Now}: ViewMessager: {message.Response ?? false}";
}
CallbackMethodNameに指定するメンバ関数はpublicにしないとダメでした。
ViewModel起点
Viewで発火させるのではなくViewmodelからも発火できます。
<Button Command="{Binding ViewModelToViewMessagerCommand}" Content="Livet Messenger: ViewModel Raise">
<i:Interaction.Triggers>
<l:InteractionMessageTrigger MessageKey="ViewModelToViewMessager" Messenger="{Binding Messenger}">
<l:ConfirmationDialogInteractionMessageAction />
</l:InteractionMessageTrigger>
</i:Interaction.Triggers>
</Button>
public InteractionMessenger Messenger { get; } = new InteractionMessenger();
public ReactiveCommand ViewModelToViewMessagerCommand { get; } = new ReactiveCommand();
public ~~ViewModel()
{
ViewModelToViewMessagerCommand.Subscribe(async _ => await ViewModelToViewMessagerAsync()).AddTo(DisposeCollection);
}
private async Task ViewModelToViewMessagerAsync()
{
var message = new ConfirmationMessage("ViewModel Raise", "title", "ViewModelToViewMessager")
{
Button = MessageBoxButton.YesNo,
};
await Messenger.RaiseAsync(message);
OutputMessage.Value = $"{DateTime.Now}: ViewModelToViewMessagerAsync: {message.Response ?? false}";
}
InformationDialogInteractionMessageAction
OpenFileDialogInteractionMessageAction
SaveFileDialogInteractionMessageAction
SaveFileDialogInteractionMessageAction
似たような使い方なので割愛(自作サンプル参照)
WindowInteractionMessageAction
Windowクラスを介さずにWindowの最小化・最大化・閉じるを行えます。
<Button Content="Window Interaction Message Close" Grid.Column="2">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<l:WindowInteractionMessageAction>
<l:DirectInteractionMessage>
<l:WindowActionMessage Action="{x:Static l:WindowAction.Close}" />
</l:DirectInteractionMessage>
</l:WindowInteractionMessageAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
まとめ
車輪の再発明をしなくて良いのはとても助かります。
他にも便利そうなアクションやビヘイビアが揃っているので、~~したいなぁと思ったら覗いてみると良いかもしれません。
おまけ
比較のためにInteractionRequestを実装しようと思ったのですが
.NET Core 3.1では下記メッセージが出て使用不可でした。
Author And Source
この問題について(Prism.Wpf(MVVM)で気軽にMessageBoxをShowしたい), 我々は、より多くの情報をここで見つけました https://qiita.com/kwhrkzk/items/cf8bf44124274cf00072著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .