简体   繁体   English

MVVM-重用具有多个ViewModel的视图

[英]MVVM - Reuse Views with multiple ViewModels

I believe one of the main benefits of MVVM is decoupling, the binding and lack of references makes things a lot more reusable. 我相信MVVM的主要好处之一就是去耦,绑定和缺少引用使事情变得更加可重用。

All MVVM examples I find have some kind of View with a ViewModel with the same naming like ExampleView has a ExampleViewModel . 我发现的所有MVVM示例都具有带有相同名称的ViewModel的View,例如ExampleView具有ExampleViewModel And always a one to one relationship, one View, one ViewModel. 而且总是一对一的关系,一个视图,一个视图模型。

But in my current project I have a form to be filled so data can be added to the data base, also the user has the option to edit the data on the data base, so this form View can be used transparently with two different ViewModels, one for adding data and one for editing data. 但是在我当前的项目中,我需要填写一个表格,以便可以将数据添加到数据库中,并且用户可以选择在数据库上编辑数据,因此该表格View可以与两个不同的ViewModel透明地使用,一种用于添加数据,另一种用于编辑数据。 I find it a little stupid to copy and paste and entire View just to have it named after its ViewModel, and not only that, if I need to change something, it will always have to be twice the work and stuff might be forgotten. 我发现复制和粘贴整个View只是为了将其命名为ViewModel有点愚蠢,不仅如此,如果我需要更改某些内容,它总是必须是工作的两倍,并且可能会遗忘一些东西。

Some frameworks have a ViewModel locator that will use this same naming convention to bind the View with the ViewModel automatically, and this makes me question the reusability of Views with many different ViewModels. 一些框架具有ViewModel定位器,该定位器将使用相同的命名约定来自动将View与ViewModel绑定,这使我质疑具有许多不同ViewModel的View的可重用性。

My question basically is: Is it there a problem in using one View with different ViewModels? 我的问题基本上是:将一个View与不同的ViewModels一起使用是否存在问题? Is it bad practice? 这是不好的做法吗? Are there any naming conventions to this particular situation? 是否有针对此特定情况的命名约定?

The lack of examples on reusability makes me question the validity of this practice. 缺乏有关可重用性的示例,使我怀疑这种做法的有效性。

There is no problem - the view is knowledgable of the view model but not vice versa. 没问题-视图可以理解视图模型,反之亦然。 This is fine with what you're doing. 您所做的一切都很好。

I would however create an interface of the common binding properties in both view models then a view model locator to expose the instance as a property. 但是,我将在两个视图模型中创建通用绑定属性的接口,然后在视图模型定位器中将实例公开为属性。 That means your binding to the implementation but don't care which one. 这意味着您绑定到实现,但不在乎哪个。

How you toggle that implementation depends on how you instantiate your view. 如何切换该实现取决于您实例化视图的方式。

As said in kidshaw answer: 正如在kidshaw中所说的那样:

Assuming that NewExampleViewModel and EditExampleViewModel share the same IExampleViewModel interface (whose properties are referenced by the view) and you strict don't want violate encapsulation, you can do it as: 假设NewExampleViewModelEditExampleViewModel共享相同的IExampleViewModel接口(其属性由视图引用),并且您严格不希望违反封装,则可以按以下方式进行操作:

var view = new ExampleView();
...
var NewVM = new NewExampleViewModel(...);
...
view.DataContext = NewVM;
...
  (or)
var EditVM = new EditExampleViewModel(...);
view.DataContext = EditVM;
...

Note that you can't use IExampleViewModel as DesignInstance in the view, as: 请注意,您不能将IExampleViewModel用作视图中的DesignInstance ,如下所示:

<UserControl ...
    d:DataContext="{d:DesignInstance Type=vmi:IExampleViewModel}"

to do that you need a concrete type, so you don't have IDE support in define the bindings. 为此,您需要一个具体的类型,因此在定义绑定时没有IDE支持。

You could use NewExampleViewModel or EditExampleViewModel as DesignInstance only while designing the view so to have IDE binding support, then remove it for the encapsulation principle. 你可以使用NewExampleViewModelEditExampleViewModel作为DesignInstance只有在设计视图,以便有IDE绑定的支持,然后将其删除了封装原则。

Perhaps you should use a user-control instead of a view. 也许您应该使用用户控件而不是视图。

You can then embed a user-control into your views. 然后,您可以将用户控件嵌入到视图中。 A user-control is not intended for view-model binding. 用户控件不适用于视图模型绑定。 It's intended to be plugged into other containers. 它打算插入其他容器中。

In your case, you have different uses for this control based on the state of your business model. 就您而言,根据业务模型的状态,此控件有不同的用途。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM