前一篇 简单的介绍了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. jquery如何判断元素是否被点击_百度知道

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <div id="parent"> <a id="a1" ...

  2. Application_Start和Application_End事件执行时间

    Application_start: 第一个访问网站的用户会触发该方法. 通常会在该方法里定义一些系统变量,如聊天室的在线总人数统计,历史访问人数统计的初始化等等均可在这里定义. Applicatio ...

  3. log4CXX第二篇---配置文件(properties文件)详解

    一.Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合使 ...

  4. LED调光,PFM即pulse frequence modulation

    PWM不是唯一的调制方式,可以PWM,也可以PFM,也可以混合调制. PWM即pulse width modulation的缩写,脉冲宽度调制,保持开关周期不变,调节开关导通时间. PFM即pulse ...

  5. 做自己的串口调试工具-MFC

    之前一共说了几个软件库,串口通讯的,xml加载的,还有动态提示的,通过这三个库就可以实现一个自己的串口调试工具,成品如下 动态加载配置文件之后如下 软件可以在xml中配置发送的字符串,不算是大工程,但 ...

  6. iOS设置状态栏的字体颜色

    设置statusBar的[前景色部分] 1.plist设置statusBar 在plist里增加一行 UIStatusBarStyle(或者是“Status bar style”也可以),这里可以设置 ...

  7. Exception和RuntimeException的区别

    Exception:在程序中必须使用try...catch进行处理. RuntimeException:可以不使用try...catch进行处理,但是如果有异常产生,则异常将由JVM进行处理.

  8. BZOJ 1497 [NOI2006]最大获利 ——网络流

    [题目分析] 最大权闭合子图. S到集合1容量为获利的大小,集合2到T为所需要付出的相反数. 然后求出最大流,然后用总的获利相减即可. [代码] #include <cstdio> #in ...

  9. python查询mysql中文乱码问题

    python2.7 查询或者插入中文数据在mysql中的时候出现中文乱码 --- 可能情况: 1.mysql数据库各项没有设置编码,默认为'latin' 2.使用MySQL.connect的时候没有设 ...

  10. UITextField 之 失去焦点 收起键盘

    1. 代理 UITextFieldDelegate 2. 设置代理 textfield.delegate = self; 3. 代理事件处理 #pragma mark - textfiled代理 -( ...