c# - MVVM 中的模型是做什么用的?

标签 c# mvvm

我已经阅读了几篇关于 MVVM 模式的文章、教程和博客文章。但是有一件事我不明白。采取三个“层”:

  • 模型
  • 查看
  • 查看模型

据我所知,MVVM 模型包含“原始”数据,例如如果是 Student 类,则为姓名和地址。 View 模型向表示模型数据的 View 公开属性。

View 模型中的属性示例

public string Name {
 get { return model.Name; }
 set { model.Name = value; }
}

模型示例

private string name;

public string Name {
 get { return name; }
 set { name = value; }
}

这听起来可能有点愚蠢,但这不会造成冗余吗?为什么我必须在模型和 View 模型中保留名称?为什么不应该完全处理 View 模型上的名称?

最佳答案

在这样一个简单的例子中,这个答案是肯定的(这是不合理的冗余)。但是,据推测,一个页面包含的不仅仅是一个 Model 对象。您可能拥有页面状态以及必须全部跟踪的多个其他模型对象。这是在 ViewModel 中完成的。

例如,您可能会在状态栏中显示有关已登录用户的其他信息,以及运行以检测文本文件更改的服务。

您可能还有一个用于编辑 Student 对象的表单。如果您打算验证这些更改,那么在验证修改之前您不希望直接编辑 Student 对象。在这种情况下,ViewModel 可以充当临时存储位置。

注意上述内容:在模型中进行验证的情况并不少见,但即便如此,您可能仍希望用户能够在编辑模型的过程中输入无效值形式。例如,如果您的模型不允许字段中的零长度值,您仍然希望允许您的用户删除该值,移动到另一个字段(例如,复制它)然后返回到该字段并完成编辑(粘贴)。如果您直接绑定(bind)到模型,那么您的验证逻辑可能无法按照您的意愿处理这种“中间”、“尚未完成”的状态。例如,在用户完成并单击“保存”之前,您可能不希望向用户提出验证错误。

您还可能在 ViewModel 中使用 Command 对象来处理按钮点击等。这些将是在模型中无用的特定领域对象。

当您需要过滤或以某种方式临时“修改”模型对象以在屏幕上显示有用的内容时,ViewModel 也很有用。例如,您可能想要显示系统中所有用户的列表以及其中前十名执行者的实时列表(每 10 秒更新一次)。或者您可能想要显示报告列表和显示总体使用率的图表等。过滤、排序和自定义数据将在 ViewModel 中进行。

另一方面,模型通常尽可能纯净。理想情况下,您只需要 POCOs那(通常)准确地模拟你的持久存储(数据库,或者你有什么)中的内容。如果您的持久存储有 FirstName 和 LastName 字段,那么您的模型也应该如此。只有在您的 ViewModel 中,您才会将它们组合起来以获得一个 Name 字段(根据 View 的需要,可以是“First Last”或“Last, First”)。

例如:

namespace Model
{
    public class Student
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

    public class Class
    {
        public string Name { get; set; }
        public float Score { get; set; }
    }
}

namespace ViewModel
{
    public class EditStudentRecordViewModel
    {
        private Model.Student _student;
        private IEnumerable<Model.Class> _studentClasses;

        /* Bind your View to these fields: */
        public string FullName
        {
            return _student.LastName + ", " + _student.FirstName;
        }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public IEnumerable<Model.Class> PassingClasses
        {
            get
            {
                return _studentClasses.Where( c => c.Score >= 78 );
            }
        }

        public IEnumerable<Model.Class> FailingClasses
        {
            get
            {
                return _studentClasses.Where( c => c.Score < 78 );
            }
        }

        public void Save()
        {
            List<string> l_validationErrors = new List<string>();
            if ( string.IsNullOrEmpty( this.FirstName ) )
                l_validationErrors.Add( "First Name must not be empty." );
            if ( string.IsNullOrEmpty( this.LastName ) )
                l_validationErrors.Add( "Last Name must not be empty." );

            if ( l_validationErrors.Any() )
                return;

            _student.FirstName = this.FirstName;
            _student.LastName = this.LastName;
            Model.Utilities.SaveStudent( _student );
        }
    }
}

关于c# - MVVM 中的模型是做什么用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14236691/

相关文章:

c# - 在 C# 中将 CSV 数据填充到现有 Excel 模板

WPF 仅数字文本框 - 使用事件或命令处理它?

java - 使用 mvvm 时从 Zk 中的嵌套类向父类发送通知

xaml - 使用模板10 MVVM在帧之间导航

c# - 关闭和清理 Socket 连接的正确方法是什么?

c# - 如何本地化数据类型消息

c# - Azure Application Insights Analytics 查询联合和列比较

c# - 无法将类型 X 转换为类型 Y。LINQ to Entities 仅支持转换 EDM 基本类型或枚举类型

c# - 游戏逻辑动态可扩展架构实现模式

java - 什么是 Java/Android 中的 View 注入(inject)?