WPF开发进阶 - Fody/PropertyChanged(二)

前一篇 简单的介绍了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

时间: 2024-08-10 21:29:04

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

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

Python开发[第二十二篇]:Web框架之Django[进阶] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 新随笔 联系 订阅 管理 随笔-124  文章-127  评论-205 Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻

【Kinect开发笔记之(二)】Kinect for windows发展历程

新版本SDK和旧版本的SDK完全兼容,如果您之前安装过旧版本的,可以直接安装新版本的SDK,但是如果您之前的开发版本是Beta版的,则需要卸载之后再安装新版本.在Kinect for Windows SDK 1.0版本中,SDK和示例文件是打包一起安装的.而在之后的版本,为了可以分别升级,微软把这两者分开独立为Kinect for Windows SDK和Kinect for Windows Developer Toolkit这两部分,所以需要分别下载安装, Kinect for Windows

iOS开发进阶

博客专栏>移动开发专栏>IOS开发进阶 分享到:新浪微博腾讯微博IOS开发进阶 iPhone开发进阶,如果你已经基本熟悉了Objective-c基本语法,你已经熟悉iOS程序开发的基础,那么我们再进一步的学习iOS开发的知识.比如多任务编程,网络,系统方面的原理,内存管理,debug或查找crash的技巧等. 收藏 订阅 最新更新文章 [移动开发] iOS界面-仿网易新闻左侧抽屉式交互 续(添加新闻内容页和评论页手势) 1.介绍有的博友看了上篇博文 iOS界面-仿网易新闻左侧抽屉式交互 ,在微

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

iOS原生地图开发进阶——使用导航和附近兴趣点检索 iOS中的mapKit框架对国际化的支持非常出色.在前些篇博客中,对这个地图框架的基础用法和标注与覆盖物的添加进行了详细的介绍,这篇博客将介绍两个更加实用的功能的开发:线路导航与兴趣点搜索.前几篇博客的链接如下: 地图基础用法详解:http://my.oschina.net/u/2340880/blog/415360. 添加大头针与自定义标注:http://my.oschina.net/u/2340880/blog/415441. 添加地图覆盖

[转]抢先Mark!微信公众平台开发进阶篇资源集锦

FROM : http://www.csdn.net/article/2014-08-01/2820986 由CSDN和<程序员>杂志联合主办的 2014年微信开发者大会 将于8月23日在北京举行.作为一线微信开发商云集.专注在开发实践方面的顶级技术活动,演讲话题极为丰富,涵盖了微信开发不同维度的多个层内容 (首批议程发布),包括:企业服务号开发和高级应用.企业号开发.如何与业务系统对接.各种高级接口功能.智能客服与LBS.HTML5社交应用.微信支付.微信电商开发等多方面(查看 参加微信开发

jqGrid 学习笔记整理——进阶篇(二)

jqGrid 学习笔记整理--进阶篇(二 ) 本篇开始正式与后台(java语言)进行数据交互,使用的平台为 JDK:java 1.8.0_71 myEclisp 2015 Stable 2.0 Apache Tomcat-8.0.30 Mysql 5.7 Navicat for mysql 11.2.5(mysql数据库管理工具) 一.数据库部分 1.创建数据库 使用Navicat for mysql创建数据库(使用其他工具或直接使用命令行暂不介绍) 2.创建表 双击打开上步创建数据库--右击T

【原创】PHP扩展开发进阶

PHP扩展开发进阶 ?作者:wf (360电商技术) 在第一期PHP扩展开发入门中,简单的介绍了PHP的总体架构和执行机制,并具体说明了怎样开发和编译一个主要的PHP扩展,最后在PHP 5.3的环境下结合zend api高速编写了一个静态的PHP扩展. 然而仅仅编译一个PHP扩展是没有实际用途的,它仅仅是一个华丽的外壳,为了使扩展实现更强大的功能,须要在扩展中开发一些有用的功能函数.在这一章中,将会着重介绍PHP内核中变量的实现.在此基础上,才干将须要的功能,使用zend api在PHP扩展中实

Java进阶(三十二) HttpClient使用详解

Java进阶(三十二) HttpClient使用详解 Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人员测试接口(基于Http协议的),即提高了开发的效率,也方便提高代码的健壮性.因此熟练掌握HttpClient是很重要的必修内容,掌握HttpClient后,相信对于Http协议的了解会更加深入. 一.简介 HttpClient是A

mysql 开发进阶篇系列 47 xtrabackup (完全备份恢复,恢复后重启失败总结)

一. 完全备份恢复说明 xtrabackup二进制文件有一个xtrabackup --copy-back选项,它将备份复制到服务器的datadir目录下.下面是通过 --target-dir 指定完全备份文件的目录,还原到datadir目录下. xtrabackup --copy-back --target-dir=/data/backups/ 可以使用xtrabackup --move-back选项恢复备份.这个选项类似于xtrabackup --copy-back,唯一的区别是它将文件移动到