前一篇 简单的介绍了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. [iOS]C语言技术视频-05-程序循环结构(do{}while();)

    下载地址: 链接: http://pan.baidu.com/s/1c02ke3m 密码: x97w

  2. HUST 1372 marshmallow

    很简单的博弈题.....算几组能得到规律了. 某个状态先手要赢 等价于 之前有一种状态是后手赢,先手可以保证让现在这个状态到达那个状态 #include<cstdio> #include& ...

  3. 6、手把手教你Extjs5(六)继承自定义一个控件

    Extjs的开发都可以遵循OOP的原则,其对类的封装也很完善了.自定义一个控件最简单的办法就是继承一个已有的控件.根据上一节的需要,我做了一个Button的子类.首先根据目录结构,在app目录下建立一 ...

  4. MySQL show master / slave status 命令参数

    一.show master status 二.show slave status Slave_IO_State SHOW PROCESSLIST输出的State字段的拷贝.SHOW PROCESSLI ...

  5. STM32的USART DMA传输(转)

    源:STM32的USART DMA传输 问题描述: 我有一个需求,AD采得一定数目的数据之后,由串口DMA发出,由于AD使用双缓冲,所以每次开始DMA的时候都需要重新设置开始的内存地址以及传输的数目( ...

  6. Keil STM32调试,使用ST-Link下载程序时提示“flash timeout.reset the target and try it again”

    参考: 很郁闷,买来没多久的 STM32F4-DISCOVERY 就挂了? STM32F103RB   Jlink调试的时候出现flash timeout.reset the target and t ...

  7. oracle 11g odbc连接串及配置

    首先先安装HA-Instant Client-v11.2.0.3.0-x86.rar 下载地址: ftp://hhdown:2-2@58.23.131.52/download/HA-Instant%2 ...

  8. ASIHTTPRequest异步请求

    我们运行程序,如果网速很慢,查询的时候会一直黑屏,直到请求结束画面才出现,这样用户体验很不好.因此同步请求一般只是在某个子线 程中使用,而不在主线程中使用.异步请求的用户体验要比同步请求好,因此一般情 ...

  9. 【转】git命令

    Git使用 1. git pull    更新服务器代码到本地a). git pull origin master是将origin这个版本库的代码更新到本地的master主分支 2. git push ...

  10. Dom编程(二)

    document是window对象的一个属性,因为使用window对象成员的时候可以省略window.,所以一般直接写document  document的方法: (1)write:向文档中写入内容. ...