MVVM中的ViewModel应该引用View吗?

时间:2010-09-08 18:03:12

标签: wpf design-patterns mvvm

在MVVM(Model-View-ViewModel)模式中,ViewModel应该引用视图。我认为不应该。但是下面的场景应该如何处理呢?我有一个视图,其中有一个选项卡控件作为主容器,此视图的viewmodel实现了一个命令,用于向选项卡控件添加新选项卡。简单的方法是允许viewmodel引用视图,然后在命令实现中以编程方式将新选项卡添加到视图中的tabcontrol。这似乎是错的。我应该以某种方式将tabcontrol绑定到viewmodel,然后实现数据/控件模板以添加新选项卡。我希望这对某些人有一些意义:)

4 个答案:

答案 0 :(得分:13)

在“纯粹的”MVVM中,ViewModel不应该真正引用View。但是,在View中提供某种形式的界面通常很方便,ViewModel可以与它进行交互。

然而,我发现我几乎再也不会这样做了。另一种方法是在View中使用某种形式的attached property或混合行为,并将其绑定到ViewModel属性。这允许您在视图中保持视图逻辑100%。此外,通过为此创建行为,您可以创建一个可重用类型,可用于在每个ViewModel-> View交互中处理此问题。我非常喜欢这种方法,而不是在ViewModel中使用任何View逻辑。

为了演示这种技术,我为表达式代码库编写了一个名为WindowCloseBehavior的示例。它演示了如何在视图中使用View中绑定到ViewModel属性的行为来处理控制Window的生命周期,包括阻止它被关闭等。

答案 1 :(得分:8)

Reed和Dan介绍了一般方法,但是在参考您的具体情况时,TabControl是一个ItemsControl,因此可以将其ItemsSource绑定到ViewModel中的数据集合,表示要显示的选项卡集。然后,每种类型的选项卡的UI可以由特定于项的数据类型的DataTemplate表示(使用DataType或DataTemplateSelector)。然后,您可以根据需要在VM中添加或删除数据项,并自动更新选项卡,而无需VM了解TabControl的任何信息。

答案 2 :(得分:3)

我发现在View上显示处理View特定功能的接口通常是一种有用的折衷方案。这是处理使用纯绑定难以完成的事情的好方法,例如指示表单关闭,打开文件对话框(虽然这通常放在自己的服务接口中)或与不适合数据设计的控件交互绑定(例如您提供的示例。)

使用界面仍然可以使View和ViewModel在很大程度上解耦,并使您能够在测试期间模拟特定的IView。

答案 3 :(得分:0)

我们中的一个人缺少明显的东西。您的选项卡控件是ItemsControl。您应该将选项卡控件的ItemsSource绑定到视图模型中的ovservable集合。在视图模型中处理命令以添加选项卡时,只需向此集合添加一个新元素,然后,您已向控件添加了一个新选项卡。