到目前为止,我还没有看到在WPF中使用模型的价值。按照惯例,我的所有ViewModel都有一个关联的Model。这些模型中的每一个都是其各自ViewModel的虚拟克隆。 ViewModel和Model类都实现INotifyPropertyChanged
,而ViewModel只是将所有内容委托给Model。
为什么要打扰模特呢?为什么我不能将模型逻辑移到ViewModel中并将其调用一天?
拥有MVVM似乎相当多余(即,不是 DRY ),并且默认情况下只使用VVM,除非某些特殊边缘情况需要模型。
如果使用显式模型类更好地支持单元测试,例如,或其他一些最佳实践,我可以看到值。
答案 0 :(得分:4)
模型可以自动生成(实体框架),也可能根本不是特定的类(想想DataTable)。
我认为,如果你说"我没有使用模型",你做实际上是使用模型,你只是不称它为那样。
答案 1 :(得分:4)
首先,即使在MVVM中,您也可以直接在VM中公开模型,并通过它将模型绑定到模型。 {Binding MyModel.MyModelsProperty}
其中DataContext = ViewModel
你不必将这一切包裹起来,除非这只是你的风格。
ViewModel和Model有不同的职责。例如,考虑使用文件夹的树视图设计文件资源管理器。树视图中的每个节点都是目录/文件夹。目录是模型,它们具有与文件系统相关的属性。 ViewModel可以包装或公开TreeView节点的这些属性以显示(例如目录的名称),但它还添加了诸如“IsEditing”和“IsExpanded”之类的附加信息,以确定节点所处的状态。 / p>
答案 2 :(得分:4)
你刚才谈到MVVM中的一种模式,实际上还有更多。
在Stateful viewmodel中,你实际上并没有将事物委托给模型,Viewmodel本身维护它的状态,正如你在这种模式中所说,你几乎可以忽略模型,因为你可以在VM本身拥有状态。
在业务逻辑和表示,数据之间创建隔离 应该从视图中删除。有状态视图模型模式移动 使用XAML数据绑定将数据导入视图模型。这允许视图 在不构建视图的情况下进行测试的模型,它允许视图 改变,对业务逻辑的影响最小。
在Stateless viewmodel中,您将调用委托给Model,这可能就是您所指的。
请注意,您不一定在INotifyPropertyChanged
中实施Model
。只要您不直接在Model中更改属性,只需在VM中实现它即可。
那么为什么我们需要VM和Model? VM用于支持视图,如提供命令等,而Model只是为了保持数据摘要相同。
答案 3 :(得分:4)
该模型只是低级应用程序数据。
视图模型更具体。
这意味着模型和视图模型之间没有1:1的关系。
因此,如果您只显示低级数据而没有大量额外的逻辑,功能,摘要,聚合,过滤器等,您可以取消视图模型并直接使用模型。您的项目似乎就是这种情况。
答案 4 :(得分:2)
根据我的经验,当您使用Domain模型作为ViewModel(作为VM的属性)时,您最终会遇到许多需要您获取文本值并存储在其他位置的键,或者您最终添加无论如何,VM的属性。您的视图通常具有的信息不仅仅是一个单一的域模型(例如相关对象,显示值,文本状态值等等),这是Domain模型不需要的东西,最终会对其进行权衡。视图模型专用于视图的需要,它使视图编码简单且不复杂。
答案 5 :(得分:2)
通常,我的模型最终成为数据访问层,无论是通过实体框架,WCF代理还是其他类。
根据并发问题,类可以是静态的或实例化的。如果您可以将行为分开,则可以将DAL类“拆分”为每个视图模型的单独模型,但重复的代码可能会成为问题。
答案 6 :(得分:2)
维基百科:MVVM
模型:与经典MVC模式一样,模型指的是(a)表示真实状态内容的域模型(面向对象的方法),或(b)表示该内容的数据访问层(以数据为中心的方法。)
您的ViewModel
不能替代您的域Model
。它充当视图和模型之间的中间层,包括命令,将视图绑定到视图,验证等。
您的域模型也应该可以在ViewModels
之间重复使用。如果您在VM中实现它,则最终会通过在多个VM之间共享特定的VM逻辑来滥用 DRY 原则。
答案 7 :(得分:1)
如果您将其视为抽象,那么假设您需要构建一个屏幕来显示Employees列表并进行选择,搜索或过滤。然后我们在组件中分解它。你需要:
Employee
班级(型号)EmployeeManagementViewModel
用于准备和展示您的员工列表并管理您的视图的状态更改(例如,可以包含SelectedEmployee
,过滤搜索文本等)以供您{{1}使用} EmployeeManagementView
)您很可能已经有EmployeeManagementViewModel
课程。如果是这种情况,那么您只需要在Employee
中将该模型公开为EmployeeManagementViewModel
员工。
如果您不已经拥有Employee类,您可以决定创建ObservableCollection
并在EmployeeViewModel
添加Employee
属性,例如FirstName
,{ {1}}等等。
从技术上讲,这会有效,但从概念上来说,这让我感到困扰,因为LastName
不是一个员工(它包含一名员工)。如果您正在抽象现实,那么Employee的蓝图不应包含View使用的属性或方法。对我而言,员工应该是一个可以实现EmployeeViewModel
的POCO,而不仅仅是那个。您正在将View状态与Model本身分开。拥有员工POCO使UnitTest变得更容易,创建模拟员工,通过ORM将其映射到数据库表等。
顾名思义,ViewModel是View的模型,Model是您的业务领域的模型
无论如何,这就是我的看法。当我开始做MVVM工作时,我遇到了同样的问题,但多年来似乎有道理。