Wpf MVVM中的ViewModel应该具有多少视图不可知性?

Wpf MVVM中的ViewModel应该具有多少视图不可知性?,wpf,javafx,design-patterns,mvvm,Wpf,Javafx,Design Patterns,Mvvm,让我们想象一个非常简单的UI,其中有一个复选框列表。单击其中任何一个按钮时: 1) 如果未选中该复选框,则应使用该复选框名称创建一个工作区(该工作区中有更多的逻辑,但这与问题无关)。然后复选框自然被选中 2) 如果它已经被选中,它将变为未选中,并将销毁关联的工作区 实现这一点的直接形式是让视图查看已单击复选框的状态,并根据是否已选中该复选框,执行viewModel.CreateWorkSpace()或viewModel.destroyWorkspace()。但是这意味着这个逻辑在视图中——我觉得

让我们想象一个非常简单的UI,其中有一个复选框列表。单击其中任何一个按钮时:

1) 如果未选中该复选框,则应使用该复选框名称创建一个工作区(该工作区中有更多的逻辑,但这与问题无关)。然后复选框自然被选中

2) 如果它已经被选中,它将变为未选中,并将销毁关联的工作区

实现这一点的直接形式是让
视图查看已单击复选框的状态,并根据是否已选中该复选框,执行
viewModel.CreateWorkSpace()
viewModel.destroyWorkspace()
。但是这意味着这个逻辑在
视图中
——我觉得最好在
视图模型中

我已经读到,出于各种原因,
ViewModel
不应该知道
视图
。但是一件事是对
视图
(例如对象引用)没有物理依赖性,而另一件完全不同的事是甚至没有意识到
视图
可能有复选框,如本例中所示

它给我的印象是,实际上使
视图
视图模型
有这么大的不同并没有什么意义,事实上,
视图模型
越接近
视图
,就越容易在
视图
视图模型
之间绑定数据

我应该如何处理这种情况,为什么


谢谢

我们的想法是将视图和视图模型解耦。 您应该能够单独实例化viewmodel。 其主要原因不是某种模糊的整洁或其他什么。 主要原因是,通过实例化离散类,您可以轻松地对代码执行测试

视图应该查看与显示数据和允许用户交互相关的内容。 viewmodel应该具有作用于这些交互并向视图显示数据的代码。 这并不意味着视图应该没有任何代码。 但是,如果有代码,它应该是特定于视图的。 使用行为等可重用代码是个好主意。 因为这样你就可以手动测试它们并证明它们是有效的。然后重新使用经过验证的代码。 与转换器、验证器等类似

所有代码

在视图中使用所有

我认为理论上可以编写一个没有转换器、验证器或行为的应用程序。我从来没有见过一个严肃的商业应用程序没有这三个功能

视图对viewmodel一无所知的重要性不如视图对viewmodel一无所知的重要性。 除非还为其实例化了viewmodel,否则不会实例化视图以执行测试。 但这并不意味着你应该把所有的代码都塞进代码隐藏中

这到底是为什么? 因为MVVM之神会用他的闪电击倒你? 不。 因为这将使未来的发展更容易? 可能吧,但通常你不会注意到

为什么呢? 因为用控件实例化视图非常慢。 他们不可避免地有很多你无法模仿的依赖性。 它可能依赖于应用程序中的资源,因此您必须实例化应用程序并合并资源字典。 视图通常依赖于大量的库、图片、用户控件等。 没有一个是你可以嘲笑的。 所以你需要一切。 当您在一些测试运行程序中自动实例化所有内容并单击按钮等时。。。 你的头会很痛,你会发现你理论上希望每10分钟在几秒钟内完成的2000次测试比那几秒钟要长得多。 如果在测试中实例化视图,则无法执行“正确的”TDD

回答您的工作区复选框问题。 这取决于工作空间是什么

一种常见的模式是在绑定到每个复选框的ischecked属性的viewmodel属性的setter中启动代码。 这可能是在viewmodel中显示的每个复选框,其中包含工作区的名称、类型或执行该操作所需的任何内容。 每一个都会持有对它正在创建的这些东西的某种引用,这样当被检查的值变为false时,它就可以处理它们或任何东西