平时我们用WPF写代码的时候,界面显示需要使用到的Model是一个类,这个类要继承自IPropertyChanged接口,例如: public class Person : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value;OnPropertyChanged("Name"); }
        }
        private int age;
        public int Age
        {
            get { return age; }
            set { age = value;OnPropertyChanged("Age"); }
        }
       private bool isSelected = false;
        /// <summary>
        /// 做界面显示时,标识是否被选中
        /// </summary>
        public bool IsSelected
        {
            get { return isSelected; }
            set { isSelected = value;OnPropertyChanged("IsSelected"); }
        }
    }而我想把这个Person对象存到数据库时,这个IsSelected属性又没有必要,而且存到数据库对应的model也不需要实现INotifyPropertyChanged接口写一大堆的,如下:public class Person1
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }这样才是传统三层里的很简洁的model。
再比如EF的Model要显示到WPF界面上,需要另外建一个model去实现INotifyPropertyChanged接口,然后写一堆方法实现WPF中MVVM中的model与EF中的model相互转换吗?

解决方案 »

  1.   

    写个基类实现接口和一些可能用到的共有属性(比如IsSelected),然后其他类继承就行了
      

  2.   

    MVVM 是 UI 层模型,跟三层模型根本就是两回事,它是在三层模型中的 UI 层中的。你是把这个基本概念搞混了。
    Model 是用来跨层通讯的,它不可能纠结什么前端里边的或者服务器里边的什么”充血的“功能。所以 Model 中不可能有什么 INotifyPropertyChanged。有这个的是 MVVM 中的 VM层,而不是 三层中的 Model。三层的 Model 定义,只是为了通讯时序列化、反序列化保持高效率、直观容易调试、适应不同版本随时增加或者删除属性时的灵活格式。所以它定义个class Person
    {
        public string Name;
        public int Age;
        public DateTime RegistDate;
        .......
    }这样的失血模型的字段定义就足够了。Model 用来进行简单地序列化、反序列化,所以 MVVM 中几乎可以忽略 M 的作用,而重点其实是丰富的前边万化的 V --> VM 的双向绑定机制。而这个机制的 oneway 方向,也就是 VM 触发 V 的那个方向,就是靠你说的那类东西(你说的大致是最基础最常见的机制的四分之一、五分之一)来实现的。
      

  3.   

    所以,实际上前端可能写一个极其简单的 PersonModel 类型,或者干脆根本不扯上什么 Model 定义,而是在 Person 这个 ViewModel 中写上两个 JObject GetModel();   //或者使用 ExpandoObject
    void SetModel(Jobject);       //或者使用 ExpandoObject这就够了!!!!
      

  4.   

    JObject GetModel();   //或者使用 ExpandoObject
    void SetModel(Jobject x);       //或者使用 ExpandoObject可以说,VMMV 中的 M,毫不起眼,基本上是个最底层的调用后台接口时才用一下的东西。编程设计全部从需求出发,从千变万化的 View 出发,然后重构和优化 ViewModel,前端工程师满脑子几乎只有 V 和 VM 的关系问题。基本上对于有点经验的开发者,把什么”增删改查“看成是最低级和机械化的 model 抛出和返回,只有没有创意的前端工程师才会满脑子只有 Model 概念。
      

  5.   

    传统的MVVM确实需要实现INotifyPropertyChanged接口,再不使用基类的情况下使用MVVMLight也可以。至于显示EF获取的数据到UI,一般是需要创建对应的DbSet类来储存数据。
      

  6.   

    MVVM
    是 Model  View  ViewModel 的简称
    他是 MVC 的变种,或是说是 MVC 的引申
    由于 MVC 的关系过于宽泛,且 C 又因没多大用处而被丢弃,却又在 V 中加入大量控制逻辑(本应是 C 的)
    MVVM 就是为调和这一情况而出现的需要实现 INotifyPropertyChanged 接口的是 ViewModel(VM),而不是 Model(M)
    目的是让 V 自动反映出数据的变化
    而你的 Person 应隶属于 Model(或更上层)而非 ViewModel
      

  7.   

    Person 这个字眼儿,我们可以分为 PersonViewModel 和 PersonModel 两类。而 MVVM 编程中,前端工程师满脑子想的就是 V 跟 VM 的关系设计问题。只有极个别的几分钟,需要调用一下远程 BLL 数据服务的时候,才调用一下后台接口用来上传或者下载 Model 数据,这个时候才用到 PersonModel。所以许多时候,甚至写一个通用的解析和抽取 Model 对象代码,甚至直接用 ExpandoObject 或者 JObject 来直接提供给后台接口作为通用解析数据 Model 定义,而不必设计什么失血模型 PersonModel。MVVM 中还给 Model 留个名词儿,其实并不怎么关心 Model。
      

  8.   

    说到思路,有的人满脑子只有数据库表,缺乏前端设计创意,不尊重用户千变万化的需求特点,这个时候就觉得 Model 很大。如果你做多了前端就知道,它虽然在每一个小模块中都有前后台通讯代码,但是 Model 毕竟只是千篇一律地调用一下后台服务时提供基础数据参数用的,根本不可能含有——也必须随时注意脱掉—— ViewModel 的主要功能特征。
      

  9.   

    举个例子吧,假设你不喜欢在 Person 中写 SetModel(m)、GetModel() 这类代码,那么你可能写这类声明 public class Person : INotifyPropertyChanged
        {
            [Model]
            public string Name.....
    这样的声明,然后你自己写一个通用方法,从 ViewModel 中找到所有标记为 ModelAttribute 的属性,在你调用后台数据服务时反射地产生 通用 ExpandoObject或者 JObject 对象。这样就能自动、通用地搞定所有 model 了。数据结构毕竟是设计的最低级基础。但是 Model 如此简单,纠结它并没啥意思。