我相信MVVM的一个主要好处是解耦,绑定和缺少引用使事情变得更加可重用。
我找到的所有MVVM示例都有某种View with ViewModel,其命名方式与ExampleView
相同ExampleViewModel
。并且始终是一对一的关系,一个View,一个ViewModel。
但是在我当前的项目中,我有一个要填充的表单,因此数据可以添加到数据库中,用户也可以选择编辑数据库中的数据,因此这个表单View可以透明地用于两个不同的ViewModel,一个用于添加数据,另一个用于编辑数据。我觉得复制和粘贴以及整个View只是为了让它以ViewModel的名字命名有点愚蠢,而且不仅如此,如果我需要改变一些东西,它总是必须是工作的两倍而且可能会遗忘一些东西。
某些框架有一个ViewModel定位器,它将使用相同的命名约定自动将View与ViewModel绑定,这让我质疑具有许多不同ViewModel的Views的可重用性。
我的问题基本上是:使用一个View与不同的ViewModel有问题吗?这是不好的做法吗?这种特殊情况是否有任何命名约定?
缺乏可重用性的例子让我质疑这种做法的有效性。
答案 0 :(得分:3)
没有问题 - 视图对视图模型是可知的,但反之亦然。这对你正在做的事情很好。
然而,我会在两个视图模型中创建公共绑定属性的接口,然后创建一个视图模型定位器,以将实例公开为属性。这意味着您对实现的绑定,但不关心哪一个。如何切换该实现取决于您实例化视图的方式。
答案 1 :(得分:2)
正如在孩子们的回答中所说:
假设NewExampleViewModel
和EditExampleViewModel
共享相同的IExampleViewModel
接口(其属性由视图引用)并且您严格不希望违反封装,您可以这样做:
var view = new ExampleView();
...
var NewVM = new NewExampleViewModel(...);
...
view.DataContext = NewVM;
...
(or)
var EditVM = new EditExampleViewModel(...);
view.DataContext = EditVM;
...
请注意,您无法在视图中将IExampleViewModel
用作DesignInstance
,因为:
<UserControl ...
d:DataContext="{d:DesignInstance Type=vmi:IExampleViewModel}"
要做到这一点,你需要一个具体的类型,所以你没有IDE支持定义绑定。
您可以在设计视图时使用NewExampleViewModel
或EditExampleViewModel
作为DesignInstance
,以便具有IDE绑定支持,然后根据封装原则将其删除。
答案 2 :(得分:1)
也许您应该使用用户控件而不是视图。
然后,您可以将用户控件嵌入到视图中。 用户控件不适用于视图模型绑定。 它打算插入其他容器中。
在您的情况下,根据业务模型的状态,您对此控件有不同的用途。