在WPF MVVM中的ViewModel中关闭窗口

时间:2016-05-09 18:42:18

标签: c# .net wpf xaml mvvm

我有一个带有一些内部代码的ViewModel需要关闭我的viewmodel绑定的窗口。到目前为止,我有:

MyWindow.xaml.cs

$("#side-nav-clear").on("click", function() {
    $("#sidenav-overlay").trigger("click");
    return false;
});

MyVM.cs

public class MyWindow : Window
{
    public MyWindow()
    {
        InitializeComponent();

        DataContext = new MyVM(this);
    }
}

这非常有效,但我在MyVM和My Window之间创建了一个不需要的依赖关系,或者至少不是这样的。

所以这是我的问题:有没有办法关闭窗口而没有直接将窗口的引用传递给视图模型?

更新 - Possible Duplicate

不同的问题和接受的答案,我没有任何命令绑定我无法将窗口作为命令参数传递。

可能重复的问题显示一些vm代码绑定为按钮的命令。我没有尝试在命令绑定范围内执行Window.Close()。

2 个答案:

答案 0 :(得分:1)

如果您使用框架,他们通常会有一个信使系统,可以播放整个节目收听的信息。一个简单的系统有一个关闭窗口消息,它是广播的,只有窗口监听,因此允许视图模型广播他们希望窗口关闭,只有他们的窗口接收它。

在MVVMLight网站上,有一个关于使用他们的信使系统安全关闭应用程序的博客,允许应用程序的所有部分在关闭之前正确清理:

http://blog.galasoft.ch/posts/2009/10/clean-shutdown-in-silverlight-and-wpf-applications/

答案 1 :(得分:0)

在MVVM中,ViewModel不应该知道任何UI类,更不用说了解它所链接的特定View对象。

对于完全解耦的解决方案,您可以在“视图”窗口上创建附加属性,然后可以将其绑定到ViewModel上的相应属性。对this question的评分最高的答案有详细信息。

如果您想将此方法应用于非模态窗口和模态窗口,则需要对此代码进行一些小调整。

private static void DialogResultChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
{
    var window = target as Window;

    if (window == null)
        return;

    if (window.IsModal())
        window.DialogResult = args.NewValue as bool?;
    else
        window.Close();
}

其中IsModel()被定义为Window扩展方法

public static class WindowExtender
{
    public static bool IsModal(this Window window)
    {
        var fieldInfo = typeof(Window).GetField("_showingAsDialog", BindingFlags.Instance | BindingFlags.NonPublic);
        return fieldInfo != null && (bool)fieldInfo.GetValue(window);
    }
}