如何关闭从视图模型(卡利+ WPF)对话窗口?(How to close dialog window

2019-06-23 12:45发布

我有ViewModel1和视图1与它相关联。 我开始对话框窗口ViewModel2使用(有些另一个视图模型) IWindowManager对象。 从代码ViewModel2类:

windowManager.ShowDialog(new ViewModel());

所以,我有对话窗口与视图1的用户控制。

我的答案是下一个-我可以用红色的关闭按钮关闭对话框窗口,但如何用我特定的按钮(包含在关闭它View1用户控件),类似“取消”以关闭命令按钮( Command={Binding CancelCommand}CancelCommand当然包含在ViewModel1类。

Answer 1:

这是,如果您的视图模型扩展更容易Caliburn.Micro.Screen

TryClose();


Answer 2:

你可以得到当前视图(在你的情况下,对话窗口)与执行IViewAware您的视图模型的接口。 然后,你可以调用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我的样本。



Answer 3:

一个清洁的方式(看个人口味主题),我用了很多是使用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注入依赖更加容易,那么你的视图模型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>();
}

如果没有一个子容器模式,你需要手动注入母公司dependeync到子

    yield return Result.ShowDialog<MyViewModel>().Configure(m => m.SomeData = this.SomeData);


文章来源: How to close dialog window from viewmodel (Caliburn+WPF)?