前一篇 简单的介绍了Fody/PropertyChanged的使用方法, 这一篇,我们详细介绍它的一些比较重要的特性和规则

1. Attributes

通过在类或属性上标记这些特性,可以在编译代码时,注入特定的功能

ImplementPropertyChangedAttribute

为类标记此特性,可以实现INotifyPropertyChanged接口

[ImplementPropertyChanged]
public class Person
{
public string Name { get; set; }
}

AlsoNotifyForAttribute

在实现通知时,也同时通知其它属性

public class Person : INotifyPropertyChanged
{
[AlsoNotifyFor("FullName")]
public string GivenName { get; set; } [AlsoNotifyFor("FullName")]
public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; public string FullName { get; set; }
}

在GivenName或FamilyName变化时,会同时也通知FullName的变化

DoNotNotifyAttribute

顾名思义,就是在编译时,不在此属性中注入变化通知的代码

public class Person : INotifyPropertyChanged
{
public string GivenName { get; set; }
[DoNotNotify]
public string FamilyName { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}

DependsOnAttribute

设置一个属性,在它依赖的属性变化时,通知此属性发生变化

public class Person : INotifyPropertyChanged
{
public string GivenName { get; set; } public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; [DependsOn("GivenName","FamilyName")]
public string FullName { get; set; }
}

DoNotSetChangedAttribute

通过约定,在实现的类里,如果有一个属性是IsChanged

 public bool IsChanged { get; set; }

在其它类发生变化时,此类的值会自动被设置为True,

如果希望在某个属性变化时,不响应此规则,可以将属性标记为DoNotSetChangedAttribute

public class Person: INotifyPropertyChanged
{
[DoNotSetChanged]
public string FullName { get; set; }
public bool IsChanged { get; set; } public event PropertyChangedEventHandler PropertyChanged;
}

在FullName变化里,不会将IsChanged设置为True

DoNotCheckEqualityAttribute

默认情况下,所有注入的变化响应,都会检查是否相等,如果相等,则不会进行通知;但在某些时候,我们也许需要无论是否相等都进行通知,这个时候,可以在属性上标记DoNotCheckEqualityAttribute以跳过是否相等的检查

public class Person: INotifyPropertyChanged
{
[DoNotCheckEquality]
public string FullName { get; set; }
public bool IsChanged { get; set; } public event PropertyChangedEventHandler PropertyChanged;
}

这样,在给FullName赋值时,无论是否和之前的值相等,都会进行通知。

2. BeforeAfter

有时候,我们需要在值发生变化时,访问变化之前和之后的值,比如做验证时,我们可以通过加入下面的方法实现:

public void OnPropertyChanged(string propertyName, object before, object after)

比如,我们写的代码:

public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged; public string Name { get; set; } public void OnPropertyChanged(string propertyName, object before, object after)
{
//Perform property validation
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

在编译时,对应的代码为:

public class Person : INotifyPropertyChanged
{
private string name; public event PropertyChangedEventHandler PropertyChanged; public string Name
{
get { return name; }
set
{
object before = Name;
name = value;
OnPropertyChanged("Name", before, Name);
}
} public void OnPropertyChanged(string propertyName, object before, object after)
{
//Perform property validation
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

3. EqualityChecking

在设置属性的值之前,会进行是否相等的检查:

public string Property1
{
get
{
return property1;
}
set
{
if (!String.Equals(property1, value))
{
property1 = value;
OnPropertyChanged("Property1");
}
}
}

用于检查是否相等的方法依赖于属性的数据类型,按照下面的顺序或规则进行比较:

  • 如果类型是Nullable,则使用 Nullable.Equals(T?,T?)方法比较
  • 如果类型包含有静态的方法Equals,则使用静态的方法对比两个参数
  • 如果类型有==方法,则使用==比较参数
  • 使用Object.Equals(object,object)比较

4.实现IsChanged标志

在上面我们已经简单的介绍了IsChanged属性,具体的实现代码如下:

  • 书写的代码
public class Person : INotifyPropertyChanged
{
public string Name { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public bool IsChanged { get; set; }
}
  • 编译对应的代码 (省略比较的代码
public class Person : INotifyPropertyChanged
{
string name;
bool isChanged;
public event PropertyChangedEventHandler PropertyChanged; public virtual void OnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
} public string Name
{
get { return name; }
set
{
name = value;
IsChanged = true;
OnPropertyChanged("Name");
}
} public bool IsChanged
{
get { return isChanged; }
set
{
isChanged = value;
OnPropertyChanged("IsChanged");
}
}
}

这样,在Name设置新值后,IsChanged属性会被设置为True

当然,在代码逻辑中,在适当的时候需要手动将IsChanged设置为false

还有一些配置和规则,可以参见https://github.com/Fody/PropertyChanged/wiki

WPF开发进阶 - Fody/PropertyChanged(二)的更多相关文章

  1. WPF开发进阶 - Fody/PropertyChanged(一)

    INotifyPropertyChanged 在WPF MVVM模式开发中,实现INotifyPropertyChanged的ViewModel是非常重要且常见的类: public class Mai ...

  2. 网站开发进阶(四十二)巧用clear:both

    网站开发进阶(四十二)巧用clear:both 前言 我们在制作网页中用div+css或者称xhtml+css都会遇到一些很诡异的情况,明明布局正确,但是整个画面却混乱起来了,有时候在IE6下看的很正 ...

  3. 网站开发进阶(三十二)HTML5之FileReader的使用

    HTML5之FileReader的使用 HTML5定义了FileReader作为文件API的重要成员用于读取文件,根据W3C的定义,FileReader接口提供了读取文件的方法和包含读取结果的事件模型 ...

  4. Python开发【第二十二篇】:Web框架之Django【进阶】

    Python开发[第二十二篇]:Web框架之Django[进阶]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...

  5. MVVM模式和在WPF中的实现(二)数据绑定

    MVVM模式解析和在WPF中的实现(二) 数据绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  6. 示例:WPF开发的简单ObjectProperyForm用来绑定实体表单

    原文:示例:WPF开发的简单ObjectProperyForm用来绑定实体表单 一.目的:自定义控件,用来直接绑定实体数据,简化开发周期 二.实现: 1.绑定实体对象 2.通过特性显示属性名称 3.通 ...

  7. 简化MVVM属性设置和修改 - .NET CORE(C#) WPF开发

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. 简化MVVM属性设置和修改 - .NET CORE(C#) WPF开发 阅读导航 常用类属性设 ...

  8. 当我们说线程安全时,到底在说什么——Java进阶系列(二)

    原创文章,同步发自作者个人博客,转载请以超链接形式在文章开头处注明出处http://www.jasongj.com/java/thread_safe/ 多线程编程中的三个核心概念 原子性 这一点,跟数 ...

  9. iOS原生地图开发进阶——使用导航和附近兴趣点检索

    iOS原生地图开发进阶——使用导航和附近兴趣点检索 iOS中的mapKit框架对国际化的支持非常出色.在前些篇博客中,对这个地图框架的基础用法和标注与覆盖物的添加进行了详细的介绍,这篇博客将介绍两个更 ...

随机推荐

  1. js 各种常用js验证

    判断http或者https var http = 'https:' == document.location.protocol ? false : true; js的类型检测方式 /**** js的类 ...

  2. CentOS 6.4 x64 Percona-Server-5.6.15 源码安装

    首先下载 Percona-Server-5.6 http://www.percona.com/downloads/Percona-Server-5.6/LATEST/source/ 然后必须先安装cm ...

  3. 浅谈web应用的负载均衡、集群、高可用(HA)解决方案(转)

    1.熟悉几个组件 1.1.apache     —— 它是Apache软件基金会的一个开放源代码的跨平台的网页服务器,属于老牌的web服务器了,支持基于Ip或者域名的虚拟主机,支持代理服务器,支持安 ...

  4. [Unity AssetBundle]Asset资源处理

    什么是AssetBundle 在很多类型游戏的制作过程中,开发者都会考虑一个非常重要的问题,即如何在游戏运行过程中对资源进行动态的下载和加载.因此,Unity引擎引入了AssetBundle这一技术来 ...

  5. 【转】 完美配置Tomcat的HTTPS

    Tomcat配置HTTPS的文章到处都有,过程也比较简单,随后文中会转一段过来. 但对于启用APR情况下报异常“java.lang.Exception: Connector attribute SSL ...

  6. iOS 简易环形进度条

    demo下载地址:https://github.com/haozheMa/LoopProgressDemo/tree/master ViewController中的代码 #import "V ...

  7. iOS开发——发短信,邮件

    在IOS开发中,有时候我们会需要用到邮件发送的功能.比如,接收用户反馈和程序崩溃通知等等,这个功能是很常用的.在苹果系统中,如果彼此的手机都是iOS设备,并且开通了iMessage功能,那么彼此之间的 ...

  8. LPC1768的USB使用--宏定义

    #ifndef __USBREG_H #define __USBREG_H /* usb设备中断定义 usb_devintst usb_devinten usb_devintclr usb_devin ...

  9. C#生成随机验证吗例子

    C#生成随机验证吗例子: public class ValidateCode : IHttpHandler, IRequiresSessionState { HttpContext context; ...

  10. Apache 代理(Proxy) 转发请求

    代理分为:正向代理(Foward Proxy)和反向代理(Reverse Proxy) 1.正向代理(Foward Proxy) 正向代理(Foward Proxy)用于代理内部网络对Internet ...