MVVM中的ViewModel应该引用View吗?[英] Should a ViewModel in MVVM reference the View?

本文是小编为大家收集整理的关于MVVM中的ViewModel应该引用View吗?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

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

推荐答案

里德(Reed)和丹(Dan)涵盖了一般方法,但在参考您的特定情况下,TABCONTROL是一个项目,因此可以将其项目源绑定到您的ViewModel中的数据集合,代表要显示的标签集.然后,每种类型的选项卡的UI可以由特定于项目的数据类型的DataTemplate表示(使用DataType或DatateMplatesElector).然后,您可以根据需要从VM添加或删除数据项,并自动更新选项卡,而无需VM了解TabControl.

其他推荐答案

在"纯" MVVM中,ViewModel不应真正引用视图.但是,在视图中提供某种形式的界面通常很方便,从而可以与它进行交互.

但是,我发现我几乎再也不会这样做了.另一种方法是使用某种形式的附加的属性或在内部融合行为您的视图,并将其绑定到您的ViewModel属性.这使您可以将视图逻辑100%保存在视图中.另外,通过为此创建行为,您可以创建可重复使用的类型,该类型可用于在每个ViewModeModel->视图交互中处理它.我强烈更喜欢这种方法,而不是在ViewModel中具有任何视图逻辑.

为了演示这项技术,我为表达式代码库编写了一个示例.它演示了如何在视图中使用与ViewModel中属性的视图中的行为来处理控制窗口的生命周期,包括防止其关闭等等.

其他推荐答案

我发现,在处理特定功能的视图上公开接口通常是一个有用的折衷方案.这是处理可以使用纯绑定来完成的事情的好方法,例如指示表单关闭,打开文件对话框(尽管通常会放置在自己的服务接口中)或与无法为数据设计不错的控件进行交互绑定(例如您提供的示例.)

使用接口仍然可以保持视图和视图模型在很大程度上解耦,并使您能够在测试过程中模拟特定的iView.

本文地址:https://www.itbaoku.cn/post/627695.html

问题描述

In the MVVM (Model-View-ViewModel) pattern should the ViewModel reference the view. I would think that it should not. But how should the following scenario be handeled? I have a view that has a tab control as the main container, the viewmodel for this view implements a command to add a new tab to the tab control. The easy way would be to allow the viewmodel to reference the view and then in the command implementation to just programmatically add the new tab to the tabcontrol in the view. This just seems wrong. Should I somehow bind the tabcontrol to the viewmodel and then implement a data/control-template to add the new tabs. I hope this makes some kind of sense to somebody :)

推荐答案

Reed and Dan covered the general approach but in reference to your specific case, TabControl is an ItemsControl and so can bind its ItemsSource to a data collection in your ViewModel representing the set of tabs to display. The UI for each type of tab can then be represented by a DataTemplate specific to the data type of an item (either using DataType or a DataTemplateSelector). You can then add or remove data items as needed from your VM and have the tabs update automatically without the VM knowing anything about the TabControl.

其他推荐答案

In "pure" MVVM, the ViewModel shouldn't really reference the View. It's often convenient, however, to provide some form of interface in the View whereby the ViewModel can interact with it.

However, I've found that I almost never do that anymore. The alternative approach is to use some form of attached property or blend behavior within your View, and bind it to your ViewModel properties. This allows you to keep the View logic 100% within the View. In addition, by creating a behavior for this, you create a reusable type that can be used to handle this in every ViewModel->View interaction. I strongly prefer this approach over having any View logic within the ViewModel.

In order to demonstrate this technique, I wrote a sample for the Expression Code Gallery called WindowCloseBehavior. It demonstrates how you can use a Behavior within the View bound to properties in the ViewModel to handle controlling a Window's life-cycle, including preventing it from being closed, etc.

其他推荐答案

I find that it's often a helpful compromise to expose an interface on the View that handles View-specific functionality. This is a good way to handle things that are awkward to accomplish with pure binding, such as instructing the form to close, opening a file dialog (though this often gets put in its own service interface) or interacting with controls not designed well for data binding (such as the example you provided.)

Using an interface still keeps the View and ViewModel largely decoupled and enables you to mock the specific IView during testing.