MessageBoxの表示をBlend 4から実装する

System.Windows.MessageBoxはXAMLではサポートしていないので通常はコードビハインドから書く。

コードビハインドに書くMessageBox
    • Page1.xaml.cs (抜粋)
private void button_Click(object sender,RoutedEventArgs e) {
    MessageBoxResult result= MessageBox.Show("次の画面にいきますか?","住所録", MessageBoxButton.OKCancel);
    if ( result == MessageBoxResult.OK ) 
    {
        Uri pageUri = new Uri(@"/Page2.xaml", UriKind.Relative);
        var frame = (PhoneApplicationFrame)Application.Current.RootVisual;
        frame.Navigate(pageUri);
    }
}

これが普通だ。

しかし、MVVMパターンで使用するICommandの実装クラスとしてMessageBoxをコマンドとしてラップすることで、Blend 4からXAMLのコマンドバインディングで記述することができる。

XAML上コマンドバインディングで書くMessageBox
    • MessageCommand.cs (RelayCommandは省略)
using System.Windows;
using System.Windows;
using Microsoft.Phone.Controls;

public class MessageBoxCommand : RelayCommand
{
    public string Title { get; set; }
    public MessageBoxResult Result { get; set; }

    public MessageBoxCommand()
        : base(null)
    {
        _execute = message =>
        {
            var currentPage = GetActivePage();

            if ( string.IsNullOrEmpty(Title) )
                Title = currentPage.ToString();
            Result = MessageBox.Show(message, Title, MessageBoxButton.OKCancel);
        };
    }
    public static PhoneApplicationPage GetActivePage()
    {
        PhoneApplicationPage result = null;
        Application current = Application.Current;
        if (current != null)
        {
            var phoneApplicationFrame = current.RootVisual as PhoneApplicationFrame;
            if (phoneApplicationFrame != null)
            {
                result = (phoneApplicationFrame.Content as PhoneApplicationPage);
            }
        }
        return result;
    }         
}

"Mandarine"は本コードのネームスペース。今後ソースコードをライブラリィとして公開する際にはこの名前で公開しようと思う。

    • Page1.xaml (リソースによるコマンドの宣言)


Resource要素によりMessageBoxCommandクラスのオブジェクトを宣言しており、更にXAML中でTitleプロパティも設定している。
また、x:Key属性で名前を記述することで、以降この名前でオブジェクトを参照することができる。

定義したコマンドオブジェクトはBlend 4でCommandプロパティの値として参照することができる。

ここではボタン(btnNavigate)のClickイベントに対応したEventTriggerをトリガにして起動される組込みアクション"InvokeCommandAction"のCommandプロパティにXAMLのリソースのKey属性に記述した"cmdConfirm"という名前が選択肢に表示されている。


Blend 4でボタン(btnNavigate)のビヘイビアであるEventTriggerをボタン(btnNavigate)のClickイベントにアサインすることで、上述したコードビハインドと同様にボタンがクリック(タップ)された際に実行するコマンドを割り当てることができる。

実行結果

このようにExpression Blend 4と組込みのビヘイビア(トリガ、アクション)を利用することで、コードビハインドにコードを全く書く必要無くViewを汚さず、ViewModelにも全くコードを追加せずにMessageBoxを呼び出すことができる。これは非常に強力だ。