Skip to content

Instantly share code, notes, and snippets.

@takamin
Created October 24, 2016 23:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takamin/ec92ff0fc33126f993dbc8e610ee5ab7 to your computer and use it in GitHub Desktop.
Save takamin/ec92ff0fc33126f993dbc8e610ee5ab7 to your computer and use it in GitHub Desktop.
MessageBox on MVVM Messenger Pattern - http://takamints.hatenablog.jp/entry/mvvm-messagebox
<Window x:Class="StudyDotNet.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StudyDotNet"
xmlns:vm="clr-namespace:StudyDotNet.ViewModels"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:tr="clr-namespace:StudyDotNet.Triggers"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<vm:MainWindowViewModel/>
</Window.DataContext>
<!-- ここから -->
<i:Interaction.Triggers>
<tr:MessageBoxTrigger>
<tr:MessageBoxAction />
</tr:MessageBoxTrigger>
</i:Interaction.Triggers>
<!-- ここまで -->
<Grid>
<Button x:Name="button" Content="Button"
Command="{Binding SampleCommand}"
HorizontalAlignment="Left" Margin="50,50,0,0"
VerticalAlignment="Top" Width="75"/>
</Grid>
</Window>
using System.Windows;
namespace StudyDotNet.Triggers
{
/// <summary>
/// メッセージボックスを表示するトリガーアクション
/// </summary>
public class MessageBoxAction : MessageBox.Action
{
protected override MessageBoxResult ShowMessage(
string text,
string title,
MessageBoxButton button,
MessageBoxImage icon)
{
return System.Windows.MessageBox.Show(
Window.GetWindow(AssociatedObject), text,
(title != null ? title :
Application.Current.MainWindow.Title),
button, icon);
}
}
}
using System;
using System.Windows;
using System.Windows.Interactivity;
namespace StudyDotNet.Triggers
{
/// <summary>
/// MVVM的メッセージボックスを表示するためのメッセンジャー。
///
/// MessageBox.Showメソッドで、イベントトリガーを起動する。
///
/// 実際の表示は、イベントトリガーから実行される
/// トリガーアクションに実装される。
/// </summary>
public class MessageBox
{
/// <summary>
/// MessageBoxTriggerを起動するイベント。
/// </summary>
public event EventHandler<EventArgs> ShowMessageBox;
/// <summary>
/// MessageBoxTriggerを起動するイベントの名前。
/// </summary>
public static string EventName
{ get { return "ShowMessageBox"; } }
/// <summary>
/// このクラスはシングルトン。
/// </summary>
public static MessageBox Instance
{ get; private set; } = new MessageBox();
private MessageBox() { }
/// <summary>
/// MessageBoxTriggerを起動するイベントの引数。
/// トリガーアクションへ渡されて処理される。
/// </summary>
public class EventArgs : System.EventArgs
{
public string Text { get; set; }
public string Title { get; set; }
public MessageBoxButton Button { get; set; }
public MessageBoxImage Icon { get; set; }
/// <summary>
/// メッセージボックスの結果を受け取るコールバック
/// </summary>
public Action<MessageBoxResult> NotifyResult
{ get; set; }
}
/// <summary>
/// MVVM的メッセージボックスを表示。
/// 実際にはイベントを発行してイベントトリガーを起動する。
/// </summary>
/// <param name="messageBoxText"></param>
/// <param name="title"></param>
/// <param name="button"></param>
/// <param name="icon"></param>
/// <returns></returns>
public static MessageBoxResult Show(
string messageBoxText,
string title = null,
MessageBoxButton button = MessageBoxButton.OK,
MessageBoxImage icon = MessageBoxImage.Information)
{
//メッセージボックスの結果
MessageBoxResult messageBoxResult = MessageBoxResult.Cancel;
//イベントを発行する
Instance.ShowMessageBox?.Invoke(
Instance,
new MessageBox.EventArgs()
{
Text = messageBoxText,
Title = title,
Button = button,
Icon = icon,
//コールバックで結果を受け取る
NotifyResult = result =>
{
messageBoxResult = result;
}
});
//メッセージボックスの結果を返す
return messageBoxResult;
}
/// <summary>
/// メッセージを表示するトリガーアクション実装用の抽象基底クラス。
///
/// 派生クラスでShowMessageを実装する。
/// </summary>
public abstract class Action : TriggerAction<DependencyObject>
{
/// <summary>
/// アクションの実態
/// </summary>
/// <param name="parameter"></param>
protected override void Invoke(object parameter)
{
//イベント引数の種別を検査
var messageBoxArgs = parameter as MessageBox.EventArgs;
if(messageBoxArgs == null)
{
return;
}
//メッセージボックスの表示結果を取得
MessageBoxResult result = ShowMessage(
messageBoxArgs.Text,
messageBoxArgs.Title,
messageBoxArgs.Button,
messageBoxArgs.Icon);
//コールバックで結果を通知
messageBoxArgs.NotifyResult?.Invoke(result);
}
/// <summary>
/// メッセージボックスを表示する抽象メソッド。
/// </summary>
/// <param name="text"></param>
/// <param name="title"></param>
/// <param name="button"></param>
/// <param name="icon"></param>
/// <returns></returns>
abstract protected MessageBoxResult
ShowMessage(
string text, string title,
MessageBoxButton button,
MessageBoxImage icon);
}
}
/// <summary>
/// MVVM的メッセージボックスを表示するためのイベントトリガー。
///
/// MessageBox メッセンジャーの発行するイベントで起動される。
/// </summary>
public class MessageBoxTrigger : System.Windows.Interactivity.EventTrigger
{
public MessageBoxTrigger()
: base(MessageBox.EventName)
{
SourceObject = MessageBox.Instance;
}
}
}
using System;
using System.Windows.Input;
using StudyDotNet.Triggers;
namespace StudyDotNet.Commands
{
public class SampleCommand : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{ return true; }
public void Execute(object parameter)
{
MessageBox.Show("MVVMバンザイ!");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment