LoginSignup
5
9

More than 5 years have passed since last update.

[WPF][XAML]MahApps.Metroのダイアログを使ってみる

Last updated at Posted at 2017-07-21

MahApps.Metroのダイアログを使ってみる

開発環境

  • Visual Studio 2017 (C#)
  • Visual Studioの拡張機能の「Prism Template Pack」
    • Prism.Core 6.3.0
    • Prism.Unity 6.3.0
    • Prism.Wpf 6.3.0
    • CommonServiceLocator 1.3.0
    • Unity 4.0.1
  • MahApps.Metro 1.5.0

初めに

WPFでシングルページアプリケーションを作成していても、やっぱりダイアログ表示がしたい!って時ありますよね?

でも、入力系のダイアログであれば、個人的には、カスタムダイアログではなく、フライアウトを推奨しますが、処理終了メッセージなんかは、やっぱりダイアログにしたいって時には、MahApps.Metroには、Metro風なダイアログがあるので、それを使ってみてはどうでしょうか?

MahApps.Metroのダイアログコントロール

※MahAppsのプロジェクトへのNuGet追加等の説明は省略

MahApps.Metro Dialogs

MahApps.Metroには、メッセージダイアログとプログレスダイアログがあります。
使用方法としては、非同期実行できるのでasync/awaitを付けた上で、それぞれ記述は以下のようになります。

メッセージダイアログの場合
await this.ShowMessageAsync("This is the title", "Some message");

WS000074.JPG

プログレスダイアログの場合
var controller = await this.ShowProgressAsync("Please wait...", "Progress message");

WS000075.JPG

MVVMではそのままだとエラーになる

コードビハインドでの記述であれば、そのまま使用できますが、
Prism+Unityを使ったようなMVVM複合アプリケーションの場合は、UserControlもしくは、PageのViewModelに処理を記述するため、上記の書き方では、エラーになります。

  • エラー画面

WS000073.JPG

これは、MetroWindowの拡張機能で各メッセージダイアログのため、UserControlやPageからではエラーになります。

MVVMの場合は、公式のページでIDialogCoordinatorを使って例が出ています。

Support for viewmodels
You can open dialogs from your viewmodel by using the IDialogCoordinator.
Add the following code to your Window.xaml or UserControl.xaml:

MVVMの理屈からは崩れちゃうけど

そもそもM+V+VMでは、役割を分けましょうということで直接Viewに対しての指定は行わないのですが、
単純にダイアログは、MetroWindowから呼び出されるので、以下の方法でも表示できます。

  • public MetroWindow Metro { get; set; }でプロパティを作り、カレントのMetroWindowを格納する
  • Metro.ShowMessageAsync("This is the title", "Some message");格納したMetroのShowMessageAsyncを指定する。
MainUcViewModel.cs
/// <summary>
/// MetroWindow
/// </summary>
public MetroWindow Metro { get; set; } = System.Windows.Application.Current.MainWindow as MetroWindow;
  • メッセージダイアログの場合
MainUcViewModel.cs
/// <summary>
/// メッセージダイアログ コマンド
/// </summary>
private DelegateCommand showMessageCommand;
public DelegateCommand ShowMessageCommand =>
    showMessageCommand ?? (showMessageCommand = new DelegateCommand(ShowMessageCommandExecute));

/// <summary>
/// メッセージダイアログ表示処理
/// </summary>
private async void ShowMessageCommandExecute()
{
    await Metro.ShowMessageAsync("This is the title", "Some message");
}
  • プログレスダイアログの場合
MainUcViewModel.cs
/// <summary>
/// プログレスダイアログ コマンド
/// </summary>
private DelegateCommand showProgressCommand;
public DelegateCommand ShowProgressCommand =>
    showProgressCommand ?? (showProgressCommand = new DelegateCommand(ShowProgressCommandExecute));

/// <summary>
/// プログレスダイアログ表示処理
/// </summary>
private async void ShowProgressCommandExecute()
{
    var controller = await Metro.ShowProgressAsync("Please wait...", "Progress message");

    for (var i = 0; i < 10; i++)
    {
        controller.SetProgress(1.0 / 10 * i);
        await Task.Delay(100);
    }
    await controller.CloseAsync();
}

実行結果

MahAppsDialogs.gif

まとめ

MVVM複合アプリケーションでもMahApps.Metroのダイアログを使う場合に、公式にあるようにIDialogCoordinatorを使うのが良いのでしょうが、こんな方法でも一応表示はできます。
Window自体は、特に固定でView名を指定したわけではないので、このぐらいは許容範囲かなと個人的には思います。

既にQiita内でもViewModelから表示するIDialogCoordinatorを使用した方法を投稿されている方がすでにいらっしゃいました。
soiさんの投稿

WPFでいけてるダイアログを出す方法

こちらを参考にされたほうが良いかも?

補足情報

  • 確認メッセージの場合は、以下のようにオプション指定をすることで可能です。
/// <summary>
/// メッセージダイアログ表示処理
/// </summary>
private async void ShowMessageCommandExecute()
{
    var metroDialogSettings = new MetroDialogSettings()
    {
        AffirmativeButtonText = "はい",
        NegativeButtonText = "いいえ",
        AnimateHide = true,
        AnimateShow = true,
        ColorScheme = MetroDialogColorScheme.Theme,
    };

    var diagResult = await Metro.ShowMessageAsync("This is the title", "Some message", MessageDialogStyle.AffirmativeAndNegative, metroDialogSettings);
    Console.WriteLine(diagResult);
}

WS000085.JPG

5
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
9