私がよく使用するよりクリーンな方法 (個人的な好みの対象) は、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);