2010-09-08 82 views
9

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

回答

7

里德和丹涵盖了一般方法,但参考您的具体情况,TabControl是一个ItemsControl,因此可以将其ItemsSource绑定到ViewModel中的数据集合,该集合表示要显示的一组制表符。每种类型选项卡的UI都可以用特定于项目数据类型的DataTemplate表示(使用DataType或DataTemplateSelector)。然后,您可以根据需要从虚拟机添加或删除数据项,并让选项卡自动更新,而无需VM知道有关TabControl的任何信息。

+0

所有其他答案都很好。这只是涵盖我想要做的具体事情。我甚至找到了一种方法来设置视图模型中的选定项目,而无需通过绑定到我集合中lastadded模型的VM上的属性来引用视图。井井有条 ... – Johan 2010-09-08 19:19:07

3

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

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

10

在“纯”MVVM中,ViewModel不应该真正引用视图。但是,在View中提供某种形式的接口,ViewModel可以与之交互,这样做通常很方便。

但是,我发现我几乎从来没有这样做过。另一种方法是在视图中使用某种形式的attached property或混合行为,并将其绑定到ViewModel属性。这使您可以将视图逻辑在视图中保持100%。另外,通过为此创建一个行为,您可以创建一个可重用的类型,该类型可用于在每个ViewModel-> View交互中处理此类型。我强烈希望通过ViewModel中的View逻辑来实现这种方法。

为了演示这种技术,我为Expression Code Gallery编写了一个样本,名为WindowCloseBehavior。它演示了如何在视图中使用行为绑定到ViewModel中的属性来处理控制窗口的生命周期,包括防止它被关闭等。

0

我们中的一个失去了明显的东西。您的选项卡控件是一个ItemsControl。您应该将您的选项卡控件的ItemsSource绑定到您的视图模型中的可选集合。当您在视图模型中处理命令以添加选项卡时,只需向该集合中添加一个新元素,并且您已向控件添加了一个新选项卡。

相关问题