ViewModel允许关闭窗口吗?

20 浏览
0 Comments

ViewModel允许关闭窗口吗?

最近,我回答了一个关于如何绑定窗口关闭按钮的问题。请不要过多关注那个问题本身,因为那不是我困扰的事情。在那种特定情况下,我甚至不会使用我的解决方案。我肯定会使用@ChrisW的解决方案。

然后,@SpikeX的回答出现了,现在我感到困惑。但是我必须感谢他。我无法停止思考,因为直到现在我可能一直以错误的方式思考MVVM。

所以我开始进行研究:

关闭ViewModel中的窗口

MVVM的基本概念-ViewModel应该做什么?

等等...

如您所见,我并不是宇宙中唯一一个从ViewModel中关闭窗口的人。但我真的可以这样做吗?或者说我真的不应该在ViewModel中使用窗口吗?MVVM对此真的如此严格吗?我的解决方案真的违反了MVVM模式吗?

0
0 Comments

ViewModel是否允许关闭窗口?

MVVM模式中的ViewModel是否允许关闭窗口?这个问题的出现是因为在MVVM模式中,ViewModel通常不应该直接操作视图(View),包括关闭窗口。然而,在某些情况下,我们可能需要在ViewModel中关闭窗口,这就引发了这个问题。

为了解决这个问题,可以使用以下解决方法:

首先,在XAML中声明命名空间xmlns:hlp="clr-namespace:AC.Frontend.Helper",然后使用hlp:AttachedProperties.DialogResult="{Binding DialogResult}"进行绑定。这样可以在ViewModel中设置DialogResult属性,并将其与窗口的DialogResult属性进行绑定。这样,当ViewModel中的DialogResult属性更改时,窗口的DialogResult属性也会相应更改。

下面是一个示例的ViewModel代码:

public class WindowVm : ViewModelBase // ViewModel基类实现INotifyPropertyChanged
{
    private bool? _dialogResult;
    public bool? DialogResult
    {
        get { return _dialogResult; }
        set 
        {
             _dialogResult = value;
             RaisePropertyChanged(() => DialogResult);
        }
    }
    //... 其他属性
}

通过使用上述方法,我们可以在ViewModel中关闭窗口,同时保持MVVM模式的完整性。这样做的缺点是,我们无法完全测试ViewModel和与关闭窗口相关的逻辑。不过,我们需要权衡利弊,确定是否值得实现这样的解决方法。

0
0 Comments

ViewModel是否允许关闭窗口?

在我看来,ViewModel应该与其使用的客户端技术完全隔离。

由于您在实际的Window实例上调用close方法,因此需要引用一个特定于客户端的程序集(在这种情况下是WPF),这几乎使得重用该ViewModel变得不可能。

如果您想创建WPF、Silverlight、Windows Phone、Windows Store App等客户端,您将无法在所有这些客户端上使用相同的ViewModel,因为Windows Phone可能不知道WPF窗口是什么。

此外,如果在ViewModel中引用实际视图元素,单元测试ViewModel将变得更加繁琐。

因此,您可以通过某种视图适配器将其抽象化,而不是直接引用窗口。

如果ViewModel只知道这样一个接口:

public interface IView
{
    void Show();
    void Close();
}

...每个客户端都可以创建自己的实现,并将其注入ViewModel中,以便在任何给定的客户端上执行正确的操作。

关键是ViewModel对实际视图一无所知,一切都隐藏在接口的实现中。

0