19

View1がViewModel1関連付けられています。ViewModel2オブジェクトを使用して(別のビューモデル)からダイアログウィンドウを開始しIWindowManagerます。ViewModel2クラスのコード:

windowManager.ShowDialog(new ViewModel());

したがって、View1 ユーザー コントロールを持つダイアログ ウィンドウがあります。

私の答えは次のとおりです。赤い閉じるボタンを使用してそのダイアログ ウィンドウを閉じることができますが、特定のボタン (ユーザー コントロールに含まれる) を使用して閉じる方法、閉じるコマンド ( )View1を含む「キャンセル」ボタンのようなものは、もちろんクラスに含まれています。 .Command={Binding CancelCommand}CancelCommandViewModel1

4

3 に答える 3

44

ビューモデルが拡張されている場合はさらに簡単ですCaliburn.Micro.Screen:

TryClose();
于 2012-07-19T20:15:47.637 に答える
10

IViewAwareViewModel にインターフェイスを実装することで、現在のビュー (この場合はダイアログ ウィンドウ) を取得できます。Close次に、コマンドの実行時にビュー (Windowダイアログとして作成されたもの)を呼び出すことができます。

最も簡単な理由は、次から派生することですViewAware

public class DialogViewModel : ViewAware
{
    public void ExecuteCancelCommand()
    {
        (GetView() as Window).Close();
    }
}

派生が許可されていない場合は、自分で実装できます。

public class DialogViewModel : IViewAware
{
    public void ExecuteCancelCommand()
    {
        dialogWindow.Close();
    }

    private Window dialogWindow;
    public void AttachView(object view, object context = null)
    {
        dialogWindow = view as Window;
        if (ViewAttached != null)
            ViewAttached(this, 
               new ViewAttachedEventArgs(){Context = context, View = view});
    }

    public object GetView(object context = null)
    {
        return dialogWindow;
    }

    public event EventHandler<ViewAttachedEventArgs> ViewAttached;
}

注: サンプルには Caliburn.Micro 1.3.1 を使用しました。

于 2012-04-10T16:30:11.603 に答える
5

私がよく使用するよりクリーンな方法 (個人的な好みの対象) は、IResult パターンを使用することです。この方法では、ウィンドウの実装を抽象化します。

ビューモデル

public IEnumerable<IResult> CloseMe()
{
    yield return new CloseResult();
}

結果コード

public class CloseResult : Result
{
    public override void Execute(ActionExecutionContext context)
    {
        var window = Window.GetWindow(context.View);
        window.Close();            

        base.Execute(context);
    }
}

public abstract class Result : IResult
{
    public virtual void Execute(ActionExecutionContext context)
    {
        OnCompleted(this, new ResultCompletionEventArgs());
    }

    protected virtual void OnCompleted(object sender, ResultCompletionEventArgs e)
    {
        if (Completed != null)
            Completed(sender, e);
    }

    public event EventHandler<ResultCompletionEventArgs> Completed;
}

編集 (IoC にのみ必要) : さらに一歩進めたい場合は、すべての画面の基本クラスを実行します。

public abstract class ShellPresentationModel : Screen
{
    public ShellPresentationModel(IResultFactory resultFactory)
    {
        Result = resultFactory;
    }

    public IResultFactory Result { get; private set; }
}

このようにして、IoC で依存関係をはるかに簡単に注入できます。その後、VIewmodel の close メソッドは次のようになります。

public IEnumerable<IResult> CloseMe()
{
    yield return Result.Close();
}

依存関係を使用する IResult の例は次のとおりです。

public class ShowDialogResult<TModel> : Result
{
    private readonly IWindowManager windowManager;
    private readonly TModel model;
    private Action<TModel> configure;

    public ShowDialogResult(IWindowManager windowManager, TModel model)
    {
        this.windowManager = windowManager;
        this.model = model;
    }

    public IResult Configure(Action<TModel> configure)
    {
       this.configure = configure;
       return this;
    }

    public override void Execute(ActionExecutionContext context)
    {
        if(configure != null)
            configure(model);

        windowManager.ShowDialog(model);

        base.Execute(context);
    }
}

編集上記の IoC の例の例を追加するのを忘れたことに気付きました。子の IoC コンテナー パターンを使用すると、次のようになります。

public IEnumerable<IResult> ShowDialog()
{
    yield return Result.ShowDialog<MyViewModel>();
}

子コンテナ パターンがなければ、親の依存関係を手動で子に注入する必要があります

    yield return Result.ShowDialog<MyViewModel>().Configure(m => m.SomeData = this.SomeData);
于 2012-04-16T13:38:04.180 に答える