我正在使用我的mvvm应用程序正在使用的设置存在一些问题。在这里看到一些帖子后,我感觉我可能会做这个稍微错误。
我有几个包含子模型列表的模型,例如:
我们目前没有任何与这些模型直接相关的视图模型,我们只是简单地拥有代表模型列表的视图模型,例如我们有一个proformalistviewmodel,它只包含一个形式列表。
我的问题是,通过这种设置,我对于什么viewmodel应该拥有哪些数据感到有点困惑,例如ProfomalistViewModel具有对当前所选Project的引用,这些模型的所有数据管理(加载和保存形式列表)是通过DI加载的管理器类完成的。
我的问题是,我应该遵循我所看到的并拥有一个包含形式列表的ProjectViewModel,以及一个包含货件和有序项目列表等的ProformaViewModel。
原因在于,最初我们没有链接的模型,项目没有一个形式列表,而是通过管理器使用选定的项目ID(使用关系数据库)单独加载,我们'目前正在将模型更改为上述系统。
答案 0 :(得分:4)
viewmodel应该是特定功能区域的用户交互的模型
例如,如果您有一个项目列表页面,并且用户可以执行某些操作,例如删除项目,编辑项目,打印有关该项目的信息项目然后你应该设计一个viewmodel,它包含与这个接口相关的数据和动作:
e.g。 viewmodel应该包含:
* A bindable container for the project data (list of projects)
* Actions that handle edit/delete interaction
* An action to handle the print functionality
这些操作中的实际功能可能不包含在viewmodel中(VM可能已接收注入的服务,例如打印服务或项目存储库),但执行这些操作的责任在于VM。
可能还需要将每个数据项(项目)包装在视图模型中,以便可以添加其他依赖于交互的属性/操作 - 例如“selected”属性(想象用户想要多选一个视图中的项目 - 您可以将一个选定的属性添加到ProjectViewModel,它将包装每个项目,使得绑定变得容易)
您最终可能会遇到以下情况:
public class ProjectOverviewViewModel
{
public IList<ProjectViewModel> Projects { get;set; }
public ProjectViewModel SelectedProject { get;set;}
public void EditSelected()
{
// Code to open edit page for the selected project
}
public void Print()
{
}
}
和ProjectViewModel
具有可选属性
public class ProjectViewModel
{
// Either put the actual data item in here and wrap it:
public Project Project {get;set;}
// Or copy properties onto the viewmodel using automapper or some other mapping framework...
// or manually :(
// e.g. properties mirrored from the entity object:
public int ProjectId { get;set;}
public string ProjectName { get;set;}
// The selected property - now your 'Selected' logic is a function of the view/viewmodel
// not the entity. The entity should only be concerned with data persistence
public bool IsSelected {get;set;}
}
您可能还希望将视图模型合成在一起,以构建更复杂的视图。想象一下,你有一个项目页面和一个“参与项目的用户”页面,你想要另一个并排显示的页面(并允许你点击一个可以刷新用户窗格的项目) - 这可以通过合成viewmodels(通过创建另一个viewmodel,其中包含两个视图模型作为属性并连接两者之间的交互)
public class ProjectAndUserOverView
{
public ProjectOverviewViewModel ProjectOverview {get;set;}
public ProjectUsersViewModel ProjectUsers {get;set;}
// Code here to listen for property changes in ProjectOverview and if SelectedProject changes
// call ProjectUsersViewModel to refresh the data for the selected user
}
最终,您只是对用户交互进行建模,您可以实现模块化程度越高,制作更清晰,更易维护的代码就越容易
有一些很好的MVVM框架 - 我个人最喜欢的是Caliburn Micro,因为它使上述非常简单(默认情况下大量使用约定)并且很容易进入。
答案 1 :(得分:2)
MVVM是设计模式,有3个部分:Model,ViewModel,View。 DIagram看起来像这样:
http://en.wikipedia.org/wiki/Model_View_ViewModel#Pattern_description
您使用ViewModels时出错了。只有用于显示的数据应该在ViewModel中。 您的模型例如:
public class Project
{
public Proforma Pr{get;set;}
}
public class Proforma
{
public string Name{get; set;};
}
你有项目显示视图(我将ViewModel注入构造函数,tou可以使用DataContext代替):
public partial class ProjectView
{
private ProjectViewModel vm;
public ProjectView(ProjectViewModel vm)
{
this.vm = vm;
}
}
如果要在“项目”视图中显示形式名称,则应在ViewModel中将其作为字符串提供。 公共类ProjectViewModel { 私人项目公关; public string ProformaName {get {return pr.Pr.Name;}} }
如果您提供形式相似的形式,您的视图将了解模型。这将违反该模式。
答案 2 :(得分:1)
我的五分钱是MVVM是一种模式,而不是宗教。我一直使用它,因为它有意义。有很多部分MVVM未定义(比如来自命令的用户交互),我读了很多关于为了适应MVVM而创建的ViewModel(它增加了设计和对象的数量)。我建议你更多地考虑DataContext,比如“全局感兴趣的选择保存在全局DataContext中,Proforma相关数据保存在Proforma DataContext中”等等,其中DataContext是某种ViewModel。最后,你可能最终会用UI来操纵它们。
答案 3 :(得分:1)
您不应为模型对象创建ViewModel。 一般来说,ViewModel应该属于UserControl。它的作用是将您的视图(您的XAML)与您的模型(业务逻辑)连接起来。
在您的情况下,如果我理解正确,您有一堆实现业务逻辑的类(项目,发货等)。您的ViewModel将具有对业务逻辑的访问权限,并为您的视图提供要绑定的属性。
答案 4 :(得分:1)
我没有看到包含模型数据对象的视图模型有任何问题。 Viewmodels不必是“每个视图一个”。它们可以表示列表中的行或其他任何内容。
话虽如此,我很高兴直接绑定到模型对象,我做了很多。我创建一个视图模型来包装它的唯一一次是我需要视图所需的每个对象的额外状态。