web-dev-qa-db-ja.com

MVVMを使用したMahApps MessageBoxes

MahAppsメリー男性のための簡単な質問。 MVVMにCaliburn.Microを使用して、メトロスタイルの優れたコントロールを使用したアプリケーションを実装しました。新しいメッセージダイアログは見栄えは良いですが、現在、独自のラッパーを作成せずにこれらのダイアログを起動する明確な方法はありません(私は反対ではありません)。しかし、これは行われたのですか、それともビューモデルからメッセージボックスを大騒ぎせずに呼び出すことができるように欠けているものはありますか?

御時間ありがとうございます。

19
MoonKnight

MahApps.Metroメッセージダイアログを呼び出すラッパーを作成しました。MVVMプロジェクトで同じ問題が発生したためです。開いているウィンドウのリストを作成する必要がありました。最初のウィンドウは常にメインウィンドウになります。

これが私のDialogServiceコードです。

_public async Task<MessageDialogResult> ShowMessage(string message, MessageDialogStyle dialogStyle)
{
    var metroWindow = (_openedViews.First() as MetroWindow);
    metroWindow.MetroDialogOptions.ColorScheme = MetroDialogColorScheme.Accented;

    return await metroWindow.ShowMessageAsync("MY TITLE", message, dialogStyle, metroWindow.MetroDialogOptions);
}
_

このコードは、結果の有無にかかわらずダイアログを表示するために使用できます。その戻り値が_Task<MessageDialogResult>_であることがわかります。したがって、結果を取得したい場合は、ViewModelで同じように実行できます。

_MessageDialogResult result = await _dialog.ShowMessage("SOME MESSAGE HERE", MessageDialogStyle.AffirmativeAndNegative).ConfigureAwait(false);

if (result == MessageDialogResult.Affirmative)
{
    //Do something
}
_

ちなみに、ShowMessage()を呼び出すメソッドが結果を必要とする場合は、[〜#〜] [〜#〜]割り当てにasyncを付けてください。そうしないと機能しません。 (メッセージダイアログを表示するだけの場合は必要ありません)。

私のプロジェクトはFramework 4.0を使用しており、NuGetからインストールする必要があるパッケージのため、_async/await_しか使用できません。この link にアクセスして、このパッケージのMSDNドキュメントにアクセスし、パッケージ here をダウンロードできます。

それがあなたの問題を解決したことを願っています。

編集:

DialogServiceにメソッドを実装して、任意のViewModelから任意のウィンドウを開きます。このメソッドは_Microsoft Unity_フレームワークを使用してオブジェクトをインスタンス化し、次にShow()を呼び出してそれ自体を開きます。 Show()を呼び出す前に、このウィンドウをリストに追加します。

私のコードを見てください:

_public void ShowView<T>(params ParameterOverride[] parameter)
{
    var window = UnityServiceConfigurator.Instance.Container.Resolve<T>(parameter) as MetroWindow;

    if (window != null)
    {
        if (Application.Current.MainWindow != window)
        {
            window.Owner = Application.Current.MainWindow;
            var ownerMetroWindow = (window.Owner as MetroWindow);

            if (!ownerMetroWindow.IsOverlayVisible())
                ownerMetroWindow.ShowOverlayAsync();
        }

        if (!_openedViews.Contains(window))
            _openedViews.Add(window);

        window.Show();
    }
}
_

これは私のViewModelから呼び出す方法です:

__dialog.ShowView<MyView>();
_

ソフトウェア全体でウィンドウが1つしかない場合は、その参照を保存し、それを使用してShowMessageAsync()を表示できます。最初に使用するためだけにリストを作成する必要はありません。このような:

_var metroWindow = (Application.Current.MainWindow as MetroWindow);
_
19

1.1.3-ALPHA *(1.2.0になる)以降、MahAppsはVMからダイアログを起動するヘルパーを提供します。これは複数のウィンドウ設定で機能します。

1)Windowで添付プロパティを使用して、ビューモデルをダイアログサブシステムに登録します。

ビューのDataContextが、ダイアログを起動する場所からのビューモデルに設定されていると想定して、次の属性を追加します。

<Controls:MetroWindow 
    xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;Assembly=MahApps.Metro"
    Dialog:DialogParticipation.Register="{Binding}">

2)DialogCoordinatorを取得/挿入:

new MainWindowViewModel(DialogCoordinator.Instance);

3)ビューモデルからダイアログを表示します。 MahAppsがビューモデルを正しいウィンドウに結合できるように、コンテキストとして「this」を使用します。

_dialogCoordinator.ShowMessageAsync(this, "Message from VM", "MVVM based dialogs!")
19
James Willock

最初にDialogの親をConductor<Screen>にすることで、これを機能させることができました。次に、いくつかのVMアクションでダイアログを起動するために、以下を実行しました:

public async Task LaunchDialog(MyDialogVM vm)
{
   var customDialog = new CustomDialog { Title = "Some Title" };
   var view = new MyDialogView{DataContext = vm};   // instance of the view user control
   customDialog.Content = view;
   // this registers the vm with CaliburnMicro, hence all life-cycle events are available
   ActivateItem(vm);    

   await _dialogCoordinator.ShowMetroDialogAsync(this, customDialog);

}
0
Purusartha

ウィンドウのインスタンスが1つだけ表示されている場合は、次のようなことを試すことができます。

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Caliburn.Micro;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;

namespace Busyboy
{
    [Export(typeof(IShell))]
    class MainViewModel : PropertyChangedBase, IShell
    {
        public void StartPomodoro()
        {
            var mainview0 = System.Windows.Application.Current.Windows.OfType<MainView>().FirstOrDefault();
            mainview0.ShowInputAsync("New Pomodoro", "Enter a name for new pomodoro session.");
        }
    }
}

また、ウィンドウを除外できるように、各ウィンドウを識別する方法が必要です。拡張機能を含むインポート「Metro.Controls.Dialogs」に注意してください。

0
Wickramaranga