WPF - MVVM 视图模型设置

Ben*_*Ben 3 c# wpf mvvm viewmodel

我当前在 mvvm 应用程序中使用的设置存在一些问题。看到这里的一些帖子后,我感觉我可能做得有点错误。

我有几个模型,其中包含子模型列表,例如:

  • 项目 - 包含形式列表
  • 形式 - 包含订购物品的发货列表
  • 装运 - 包含集装箱列表
  • 容器 - 包含包列表

目前我们没有任何与这些模型直接相关的视图模型,而是只有表示模型列表的视图模型,例如,我们有一个仅包含形式列表的形式视图模型。

我的问题是,通过这种设置,我对哪个视图模型应该拥有哪些数据有点困惑,例如 ProfomalistViewModel 引用了当前选定的项目,这些模型的所有数据管理(加载和保存形式列表)是通过通过 DI 加载的管理器类完成的。

我的问题是我应该遵循我所看到的并拥有一个包含形式列表的 ProjectViewModel 和一个包含发货和订购项目列表等的 ProformaViewModel 。

原因是,最初我们没有链接任何模型,项目不拥有形式列表,而是通过管理器使用选定的项目 ID(使用关系数据库)单独加载,并且我们当前正在更改我上面描述的系统的模型。

Cha*_*leh 5

视图模型应该是特定功能区域的用户交互模型

例如,如果您有一个项目列表页面,并且用户可以执行某些操作,例如删除项目编辑项目打印有关项目的信息,那么您应该设计一个视图模型,其中包含与此界面关联的数据和操作:

例如视图模型应包含:

 * A bindable container for the project data (list of projects)
 * Actions that handle edit/delete interaction
 * An action to handle the print functionality
Run Code Online (Sandbox Code Playgroud)

这些操作内的实际功能可能不包含在视图模型中(VM 可能已接收注入的服务,例如打印服务或项目存储库),但执行这些操作的责任由 VM 承担。

可能还需要将每个数据项(项目)包装在视图模型中,以便可以添加其他依赖于交互的属性/操作 - 例如“选定”属性(想象一下用户想要在视图模型中多次选择多个项目) view - 您可以将选定的属性添加到 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()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

以及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;}
}
Run Code Online (Sandbox Code Playgroud)

您可能还想将视图模型组合在一起以构建更复杂的视图。想象一下,您有一个项目页面和一个“参与项目的用户”页面,并且您想要另一个页面并排显示这两个页面(并允许您单击一个项目来刷新用户窗格) - 这可以通过组合视图模型(通过创建另一个视图模型,其中包含两个视图模型作为属性并连接两者之间的交互)

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
}
Run Code Online (Sandbox Code Playgroud)

最终,您只是对用户交互进行建模,并且您可以将其做得越模块化,就越容易制作更清晰、更易于维护的代码

有一些很好的 MVVM 框架 - 我个人最喜欢的是 Caliburn Micro,因为它使上述内容变得非常简单(默认情况下它大量使用约定)并且很容易使用。