WPF框架之MVVM系列(一)

WPF框架之MVVM系列(一)

(一)定义:MVVM(Model-View-ViewModel)是在MVC(Model-View-Control)模式之后引出的新的开发模式,他与MVC模式一样用于把视图(界面)和数据进行解耦,不同的是采用ViewModel来完成数据与视图的双向绑定,通过自动化的方式承担大部分数据工作,来解决由于界面复杂化和快速迭代带来的问题。它的技术模型如下图所示

WPF框架之MVVM系列(一)

(二)MVVM技术框架
根据MVVM模型框架定义的逻辑体系, MVVM技术框架提供视图模型(ViewModel)、数据模型(Model、Collection)和服务(Service)四个组件来构建开发者的MVVM开发体系。
   MVVM.Service
Service主要负责与后端服务器进行通讯的处理。
   MVVM.Model
Model就是系统中的业务实体,是对现实中事物的抽象,开发过程中涉及到的事物都可以抽象为Model,例如客户实体中含有客户的姓名、编号、电话、住址等属性也对应了实体类中的Property,客户的下订单、付款等行为对应了实体中的方法。
   MVVM.Collection
Collection 是用来维护一个 Model的集合,它主要用于维护的是一个可以增加、删除、排序筛选的数据列表。例如订单列表、商品列表等。这些数据列表都不会在一次访问中加载完成,用户需要进行翻页等操作,这些操作触发数据更新并附加或更新到 Collection 中。Model 中的数组主要用于维护一个对象的一些不经常变化的列表属性,例如衣服对象的尺码列表、一个电脑的硬盘大小选项等,这些属性经常不需要动态添加,而是直接一次获取和展现。
   MVVM.ViewModel
ViewModel是Model、Collection与XAML(View)的中间处理机,他首要完成数据到界面、界面到数据的自动化操作。同时也是用户交互行为事件的处理中心。我们通过代码来了解MVVM对象的使用方式
   MVVM.View
View是系统界面展示,在WPF中即为XAML页面。

(三)INotifyPropertyChanged实现原理

3.1  类层次图
WPF框架之MVVM系列(一)

3.2  应用场景举例
项目用到DataGridView,用它绑定数据源后,如果数据源中的数据修改无法及时刷新到控件上,必须切换单元格的焦点才能导致刷新显示新数值,用INotifyPropertyChanged解决此问题。

WPF框架之MVVM系列(一)

WPF框架之MVVM系列(一)WPF框架之MVVM系列(一)
代码分析//Step1:定义一个类:Customer
public class Customer : INotifyPropertyChanged
{
  private string _customerName;
  private string _phoneNumber;
  
  public string CustomerName
  {
    get { return _customerName; }
    set
    {
      if (_customerName != value)
      {
        _customerName = value;
        PropertyChanged(this, new PropertyChangedEventArgs("CustomerName"));
      }
    }
  }
  
  public string PhoneNumber
  {
    get { return _phoneNumber; }
    set
    {
      if (_phoneNumber != value)
      {
        _phoneNumber = value;
        PropertyChanged(this, new PropertyChangedEventArgs("PhoneNumber"));
      }
    }
  }
  public event PropertyChangedEventHandler PropertyChanged = delegate{};
}

//Step2:创建一个绑定数据集
private BindingList<Customer> customers = new BindingList<Customer>();

//Step3:向数据集中添加数据并绑定到控件
customers.Add(new Customer() { CustomerName = "张三", PhoneNumber = "010-5263" });
customers.Add(new Customer() { CustomerName = "李四", PhoneNumber = "010-8823" });
dataGridView1.DataSource = customers;

//Step4:修改数据源
customers[0].CustomerName = "王五";

3.3  案例分析
WPF框架之MVVM系列(一)

关于public event PropertyChangedEventHandler PropertyChanged在子类实现的三种方式

WPF框架之MVVM系列(一)WPF框架之MVVM系列(一)
(1) 在构造中实现public Customer()
{
  PropertyChanged += Customer_PropertyChanged;
}
private void Customer_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
  Console.WriteLine(e.PropertyName);
}
WPF框架之MVVM系列(一)WPF框架之MVVM系列(一)
(2) 无参匿名委托public event PropertyChangedEventHandler PropertyChanged = delegate {};
WPF框架之MVVM系列(一)WPF框架之MVVM系列(一)
(3) 有参匿名委托public event PropertyChangedEventHandler PropertyChanged = delegate(object sender, PropertyChangedEventArgs e)
{
  Console.WriteLine(e.PropertyName);
};

(四)Microsoft.Practices.Prism.dll>>Microsoft.Practices.Prism.Commands>>DelegateCommand类原理分析

WPF框架之MVVM系列(一)WPF框架之MVVM系列(一)
DelegateCommand源码public class DelegateCommand : DelegateCommandBase
{
  public DelegateCommand(Action executeMethod) : this(executeMethod, () => true)
  {
  }

  public DelegateCommand(Action executeMethod, Func<bool> canExecuteMethod) : base(action, func)
  {
    Action<object> action = null;
    Func<object, bool> func = null;
    if (action == null)
    {
      action = o => executeMethod();
    }
    if (func == null)
    {
      func = o => canExecuteMethod();
    }
    if ((executeMethod == null) || (canExecuteMethod == null))
    {
      throw new ArgumentNullException("executeMethod", Resources.DelegateCommandDelegatesCannotBeNull);
    }
  }

  public bool CanExecute()
  {
    return base.CanExecute(null);
  }

  public void Execute()
  {
    base.Execute(null);
  }
}
WPF框架之MVVM系列(一)WPF框架之MVVM系列(一)
DelegateCommand《T》源码public class DelegateCommand<T> : DelegateCommandBase
{
  public DelegateCommand(Action<T> executeMethod) : this(executeMethod, o => true)
  {
  }

  public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod) : base(action, func)
  {
    Action<object> action = null;
    Func<object, bool> func = null;
    if (action == null)
    {
      action = o => executeMethod((T) o);
    }
    if (func == null)
    {
      func = o => canExecuteMethod((T) o);
    }
    if ((executeMethod == null) || (canExecuteMethod == null))
    {
      throw new ArgumentNullException("executeMethod", Resources.DelegateCommandDelegatesCannotBeNull);
    }
    Type type = typeof(T);
    if (type.get_IsValueType() && !(type.get_IsGenericType() && typeof(Nullable<>).IsAssignableFrom(type.GetGenericTypeDefinition())))
    {
      throw new InvalidCastException(Resources.DelegateCommandInvalidGenericPayloadType);
    }
  }

  public bool CanExecute(T parameter)
  {
    return base.CanExecute(parameter);
  }

  public void Execute(T parameter)
  {
    base.Execute(parameter);
  }
}





 

参考资料:

http://www.cnblogs.com/guofeiji/p/5277834.html

posted @ 2015-09-25 14:06 李华丽 阅读(...) 评论(...) 编辑 收藏