MvvmLight的抽象类ViewModelBase继承了ObservableObject这个类,我们来看看这个类:

 /// <summary>/// 一个基类,为了使它的对象属性必须具有可观察性/// INotifyPropertyChanged,INotifyPropertyChanging/// </summary>public class ObservableObject:INotifyPropertyChanged,INotifyPropertyChanging

可以看见其实它继承了INotifyPropertyChanged,INotifyPropertyChanging这两个.net里的接口,在System.dll程序集中:

#region Assembly System.dll, v2.0.50727
// C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll
#endregionnamespace System.ComponentModel
{// Summary://     Notifies clients that a property value has changed.public interface INotifyPropertyChanged{// Summary://     Occurs when a property value changes.event PropertyChangedEventHandler PropertyChanged;}
}

当属性改变时通知客户端。这个类肯定实现了这两个接口中的事件,来看下:

/// <summary>/// 如果需要,唤起PropertyChanged事件,非泛型/// </summary>/// <remarks>如果参数名在当前类的属性中不一致/// 在DEBUG条件下抛出异常VerifyPropertyName中</remarks>/// <param name="propertyName">改变的属性名称</param>/// <param name="propertyName"></param>[SuppressMessage("Microsoft.Design","CA1030:UseEventsWhereAppropriate",Justification="This cannot be an event" )]protected virtual void RaisePropertyChanged(string propertyName){VerifyPropertyName(propertyName);var handler = PropertyChanged;if (handler != null){handler(this, new PropertyChangedEventArgs(propertyName));}}

还有个就是

protected virtual void RaisePropertyChanging(string propertyName)

参数都是string类型的propertyName.

那么更好的肯定是实现这两个方法的泛型版本:

/// <summary>/// 如果需要,唤起PropertyChanged事件,泛型/// </summary>/// <typeparam name="T"></typeparam>/// <param name="propertyExpression"></param>[SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate",Justification = "This cannot be an event")][SuppressMessage("Microsoft.Design","CA1006:GenericMethodsShouldProvideTypeParameter",Justification = "This syntax is more convenient(方便) than other alternatives(选择的余地)")]protected virtual void RaisePropertyChanged<T>(Expression<Func<T>> propertyExpression){var handler = PropertyChanged;if (handler != null){var propertyName = GetPropertyName(propertyExpression);handler(this, new PropertyChangedEventArgs(propertyName));}}

注意到这里有个GetPropertyName方法:

/// <summary>/// 根据表达式提取(Extract)属性名字/// </summary>/// <typeparam name="T"></typeparam>/// <param name="propertyExpression"></param>/// <returns></returns>protected string GetPropertyName<T>(Expression<Func<T>> propertyExpression){if (propertyExpression == null){throw new ArgumentNullException("propertyExpression");}//关于Linq的文章,可以参考//http://www.cnblogs.com/lifepoem/archive/2011/12/16/2288017.html//http://www.cnblogs.com/zhili/archive/2012/12/12/LambdaExpression.htmlvar body = propertyExpression.Body as MemberExpression;if (body == null){throw new ArgumentException("Invalid argument", "propertyExpression");}var property = body.Member as PropertyInfo;if (property == null){throw new ArgumentException("Argument is not a property","propertyExpression");}return property.Name;}

关于Linq学习的博文,园子里已经有很多人写过了,可以参考lifepoem和zhili的。

这个类还有两个重要的泛型方法,Set<T>:

/// <summary>/// 把新值赋给属性,然后唤起PropertyChanged事件/// </summary>/// <typeparam name="T">属性类型</typeparam>/// <param name="propertyExpression">确认属性改变的表达式,翻译有问题</param>/// <param name="field">保存属性值的变量</param>/// <param name="newValue">改变过后的新值</param>/// <returns>事件只有在两个值不相等的情况下才被唤起</returns>protected bool Set<T>(Expression<Func<T>> propertyExpression,ref T field,T newValue){if (EqualityComparer<T>.Default.Equals(field,newValue)){return false;}RaisePropertyChanging(propertyExpression);field = newValue;RaisePropertyChanged(propertyExpression);return true;}

另外一个其实也就是把Expression<Func<T>>参数换成string参数而已

protected bool Set<T>(string propertyName,ref T field,T newValue)

之前我们的例子中的RaisePropertyChanged就是其实就是调用ViewModelBase里的RaisePropertyChanged函数,因为这个函数是虚函数,所以是调用的ViewModelBase中的RaisePropertyChanged实现:

[SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate",Justification = "This cannot be an event")]protected virtual void RaisePropertyChanged<T>(string propertyName, T oldValue, T newValue, bool broadcast){if (string.IsNullOrEmpty(propertyName)){throw new ArgumentException("This method cannot be called with an empty string", "propertyName");}RaisePropertyChanged(propertyName);if (broadcast){Broadcast(oldValue, newValue, propertyName);}}

最后一个参数如果不为true,而且不注册PropertyChanged事件将不会有任何返回结果。下篇我们介绍NotificationMessage和DialogMessage的简单使用。

转载于:https://www.cnblogs.com/johnwonder/archive/2013/01/05/2846749.html

MvvmLight学习心得三相关推荐

  1. BT源代码学习心得(三):种子文件的编码方式 -- 转贴自wolfenstein (NeverSayNever)

    BT源代码学习心得(三):种子文件的编码方式 author: wolfenstein BT的作者使用了一种比较简单易懂的编码方式来对设计种子文件.这种编码方式能够很简单得对python中的各种数据类型 ...

  2. c语言课程设计文献检索,文献检索课学习心得三篇(2)

    文献检索课学习心得 篇[3] 内容提要:通过本次文献信息检索课程的学习,有利于培养我们的信息意识.自学意识和知识创新能力,使我们养成了自主学习的习惯和独立获取信息的能力,了解了信息社会中文献信息检索的 ...

  3. STM32学习心得三十四:外部SRAM原理及实验代码解读

    记录一下,方便以后翻阅~ 主要内容: 1) IS62WV51216简介: 2) FSMC简介及相关寄存器介绍: 3) 相关实验代码解读. 参考手册: <STM32中文参考手册_V10>-第 ...

  4. 2020春季学期哈工大软件构造学习心得三

    Abstract Data Type (ADT) and ObjectOriented Programming (OOP) 前言 前两章回答了:什么是"高质量的软件". 如何从不同 ...

  5. STM32学习心得三十五(上):VS1053实验之RAM测试及正弦测试

    记录一下,方便以后翻阅~ 主要内容: 1) 硬件连接: 2) VS1053简介: 3) 相关实验及其代码解读. 实验功能:程序开启后,系统先进行RAM测试,再进行正弦测试,可以接耳机听到所设的单频声音 ...

  6. STM32学习心得十九:电容触摸按键实验及相关代码解读

    记录一下,方便以后翻阅~ 主要内容 1) 电容触摸按键原理: 2)部分实验代码解读. 实验内容 手触摸按键后,LED1灯翻转. 硬件原理图 上图,TPAD与STM_ADC用跳线帽相连,即TPAD与PA ...

  7. STM32学习心得二十一:实时时钟RTC和备份寄存器BKP特征、原理及相关实验代码解读

    记录一下,方便以后翻阅~ 主要内容 1) RTC特征与原理: 2) BKP备份寄存器特征与原理: 3) RTC常用寄存器+库函数介绍: 4) 相关实验代码解读. 实验内容: 因为没有买LCD屏,所以计 ...

  8. STM32学习心得十八:通用定时器基本原理及相关实验代码解读

    记录一下,方便以后翻阅~ 主要内容: 1) 三种定时器分类及区别: 2) 通用定时器特点: 3) 通用定时器工作过程: 4) 实验一:定时器中断实验补充知识及部代码解读: 6) 实验二:定时器PWM输 ...

  9. STM32学习心得二十六:DAC数模转换实验

    记录一下,方便以后翻阅~ 主要内容: 1) DAC数模转换原理: 2) 寄存器和库函数介绍: 3) 相关实验代码解读. 实验功能:系统启动后,按WK_UP键,输出电压加200点,对应电压值200*3. ...

最新文章

  1. svm手写数字识别_KNN 算法实战篇如何识别手写数字
  2. Linux终端命令行下的常用快捷键使用
  3. 基本系统设备感叹号更新不了_电脑识别不了U盘?别紧张,免费教你如何解决...
  4. LeetCode 295. 数据流的中位数(大小堆)
  5. python高阶函数看不懂_Python进阶:高阶函数的详细说明
  6. 《Python程序设计》——1.2 程序开发周期
  7. SQL基础E-R图画法(一)
  8. 简易售货机JAVA sql_自动售货机 - 笨拙的小Q的个人空间 - OSCHINA - 中文开源技术交流社区...
  9. e值的MonteCalo法估计
  10. mac os 下安装mysql
  11. HMI 软件内存异常,导致奔溃退出的bug
  12. tcpdf不支持html,TCPDF:无法从HTML输入生成PDF文件
  13. vscode彻底卸载记录/使用经验
  14. 旋转式直流无刷Maxon电机与copley驱动器调试
  15. win7 64 下Vim与Vundle,pathogen的安装【转】
  16. Eolink 11月企业与产品动态速览!
  17. 蓝牙耳机啥牌子音质好?听音乐最好的蓝牙耳机分享
  18. 大学生HTML个人网页作业作品:基于html css实现围棋网页(带设计报告4800字)
  19. linux监控网络端口流量,Linux如何用mrtg监控网络端口流量
  20. 京瓷m1025维修模式进不去_各种复印机维修模式进入方式

热门文章

  1. 我的博客今天0岁346天了,我领取了…
  2. 报告!钉钉宜搭的8月总结,请查收~
  3. 达摩院 AI 进入中国科技馆,首张 AI 识别新冠 CT 成科技抗疫历史见证
  4. Java 的这些坑,你踩到了吗?
  5. android 恢复出厂设置 时间,Android 恢复出厂设置后,时间不能恢复为:2013年1月1日...
  6. python字典遍历取值_Python中字典的使用
  7. Unity手游开发札记——移动平台的天气系统实现
  8. 什么是Ajax和JSON,它们的优缺点
  9. MySQL中myisam和innodb的主键索引有什么区别?
  10. SP2-0618: Cannot find the Session Identifier. Check PLUSTRACE role is enable