转载来源:http://www.cnblogs.com/TianFang/p/6240933.html

INotifyPropertyChanged接口在WPF或WinFrom程序中使用还是经常用到,常用于通知界面属性变更。标准写法如下:

class NotifyObject : INotifyPropertyChanged
    {
        private int number;
        public int Number
        {
            get { return number; }
            set { number = value; OnPropertyChanged("Number"); }
        }

private string text;
        public string Text
        {
            get { return text; }
            set { text = value; OnPropertyChanged("Text"); }
        }

public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName = "")
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

这种写法的两个问题是

  1. 对属性名使用了字符串硬编码,容易写错,也不方便重构
  2. 冗余代码,如果属性较多的时候写得想吐

我在博客文章使用CallerMemberName简化InotifyPropertyChanged的实现中介绍了通过Caller Information解决属性名称字符串硬编码的问题。但是仍然不能解决冗余代码的问题。对于第二个问题,往往是通过AOP的方式实现,一般的实现方式有两种:

  1. 通过代理对象封装
  2. 通过编译期间代码注入的方式实现

我增在项目中使用过DynamicObject封装来实现过,主要原理是用实现一个PocoNotifyWrapper的DynamicObject类,托管其属性的读写动作,并附加IntofyPropertyChanged接口实现。

这种方式是动态的AOP了,是一个通用的方式,并且扩展性比较器,可以通过继承PocoNotifyWrapper来实现多态。用它做ViewMode层还是比较方便。

不过一个不大好的地方是DynamicObject是丢失了属性类型信息的,有时绑定时会出错(如将一个TextBox的Text绑定到一个封装后的Int类型对象时会不进行自动类型转换)。要解决它还需要实现一些其它的接口,实现起来还是有些复杂的,并且项目进度比较紧张,没有太多时间来完善它。

另外一种方式是通过编译期间代码注入方式来实现:


最开始见的是PostSharp的一个实现: http://doc.postsharp.net/inotifypropertychanged-add。不过PostSharp是收费的,后来也逐渐由了许多其它的免费的解决方案。本文这里介绍的是一个开源的解决方案:Fody

使用它非常简单,首先通过Nuget安装库:PM> Install-Package PropertyChanged.Fody。然后在需要实现属性通知的类上加一个[ImplementPropertyChanged]即可:

]
  public class Person
  {

    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName => string.Format("{0} {1}", GivenNames, FamilyName);
  }

编译后生成的代码如下:

 

基本上对代码没有注入,不需要安装插件,也不影响调试,实现非常简单,非常方便。

需要注意的是,如果实现了INotifyPropertyChanged接口,即使没有[ImplementPropertyChanged]标记,默认也会注入。另外,如果要实现更多的控制,可以参看如下链接:

除此之外,还有许多关于实现的INotifyPropertyChanged文章,感兴趣的朋友可以看一下:

转载:如何优雅的实现INotifyPropertyChanged接口的更多相关文章

  1. 转载:WPF MVVM之INotifyPropertyChanged接口的几种实现方式

    原文地址:http://www.cnblogs.com/xiwang/ 序言 借助WPF/Sliverlight强大的数据绑定功能,可以比实现比MFC,WinForm更加优雅轻松的数据绑定.但是在使用 ...

  2. 如何优雅的实现INotifyPropertyChanged接口

    INotifyPropertyChanged接口在WPF或WinFrom程序中使用还是经常用到,常用于通知界面属性变更.标准写法如下: class NotifyObject : INotifyProp ...

  3. 优雅实现INotifyPropertyChanged接口——利用Lambda表达式

    原文:优雅实现INotifyPropertyChanged接口--利用Lambda表达式 参考文章 在14年的时候,曾经读过上面的参考文章,不过当时并没有怎么理解,慢慢地也就将这篇文章忘诸脑后了. 直 ...

  4. WPF系列之三:实现类型安全的INotifyPropertyChanged接口,可以不用“Magic string” 么?

    通常实现INotifyPropertyChanged接口很简单,为你的类只实现一个PropertyChanged 的Event就可以了. 例如实现一个简单的ViewModel1类: public cl ...

  5. WPF MVVM之INotifyPropertyChanged接口的几种实现方式(转)

    原地址:https://www.cnblogs.com/xiwang/archive/2012/11/25/2787358.html 序言 借助WPF/Sliverlight强大的数据绑定功能,可以比 ...

  6. INotifyPropertyChanged接口的PropertyChanged 事件

    INotifyPropertyChanged 接口用于向客户端(通常是执行绑定的客户端)发出某一属性值已更改的通知. 例如,考虑一个带有名为 FirstName 属性的 Person 对象. 若要提供 ...

  7. 【.NET深呼吸】INotifyPropertyChanged接口的真故事

    无论是在流氓腾的问问社区,还是在黑度贴吧,或是“厕所等你”论坛上,曾经看到过不少朋友讨论INotifyPropertyChanged接口.不少朋友认为该接口是为双向绑定而使用的,那么,真实的情况是这样 ...

  8. [译]WPF MVVM 架构 Step By Step(5)(添加actions和INotifyPropertyChanged接口)

    应用不只是包含textboxs和labels,还包含actions,如按钮和鼠标事件等.接下来我们加上一些像按钮这样的UI元素来看MVVM类怎么演变的.与之前的UI相比,这次我们加上一个"C ...

  9. C# ListView 控件和 INotifyPropertyChanged 接口

    ListView 控件和 DataGridView 控件 ListView 是跟 Winform 中 DataGridView 用法以及显示效果差不多的一个 WPF 控件,可以通过列表的方式方便的显示 ...

随机推荐

  1. 学习MeteoInfo二次开发教程(十一)

    1.新添加状态栏ToolStrip,可能名称为toolStripStatusLabel2 这时需要把TSSL_Coord改为toolStripStatusLabel2 2.SetMapView();语 ...

  2. GitHub提供服务简介

    |GitHub-Funcation| |Git仓库|   一般情况下,我们可以免费建立任意个GitHub提供的Git仓库.但需要私有仓库则需要最低每月支付$7. |Organization|    这 ...

  3. Specified key was too long; max key length is 767 bytes解决方案

    问题描述: 1.  使用spark sql处理数据逻辑,逻辑处理后使用 df.write.mode(saveMode).jdbc(url, tableName, connectionPropertie ...

  4. 棒槌的工作第11天-----------------------单词(select和epoll)

    https://baike.baidu.com/item/epoll/10738144?fr=aladdin epoll百科 https://baike.baidu.com/item/select%2 ...

  5. 数据库索引的数据结构b+树

    b+树的查找过程:如上图所示,如果要查找数据项29,那么首先会把磁盘块1由磁盘加载到内存,此时发生一次IO,在内存中用二分查找确定29在17和35之间,锁定磁盘块1的P2指针,             ...

  6. mosquitto broker 安装服务后启动失败

    一.失败原因 由于做项目用到Mqtt协议,需要安装mosquitto broker 服务,在自己本地笔记本电脑安装后直接启动服务是可以的.后来部署到服务器启动,报错缺少msvcr100.dll ,由于 ...

  7. jQuery入门基础(事件、DOM操作)

    http://www.w3school.com.cn/b.asp 一.事件 1.常规事件——把js事件前面的on去掉 比如:js:onclick——JQuery:click 下面是 jQuery 中事 ...

  8. 001_angular4.0框架学习

    1. Cannot find module 'angular2-in-memory-web-api' 报这个错误的时候  是没有安装这个包  要手动安装下包  命令: npm i angular-in ...

  9. vue每次修改刷新当前子组件

    刚入门vue,发现很多坑,对很多框架兼容性不太友好,比如layui等 每次删除相关信息,更新相关信息,不会主动刷新当前页面内容,只能手动刷新 第一步,我们在跟组件理由设置一个参数,用来判断是否需要刷新 ...

  10. JUnit4源码学习笔记

    先上一个在Spring-test下运行的调用栈 自底向上: JUnitStarter IDEA对JUnit的支持,调用JUnitCore.run(Runner),将注解@RunWith指定的Runne ...