转载来源: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. Submine Text3格式化HTML/CSS/JS代码

    Submine Text3格式化HTML/CSS/JS代码需要安装插件,步骤如下: 1.打开菜单--->首选项---->Package Control,输入 install package ...

  2. c#字符串to/from文本文档IO示例

    写入文本文档 class Program { static void Main(String[] args) { //写入string数组,每个string一行 string[] lines = { ...

  3. JQuery 中的选择器

    选择器:允许通过标签名,属性名或内容对DOM元素进行快速,准确的选择,浏览器兼容性很好. 普通选择器 选择器 功能 返回值 #id 根据给定的ID匹配一个元素 单个元素 element 根据给定的元素 ...

  4. SpringBoot+Mybatis实现关联查询

    SpringBoot+Mybatis实现关联查询 今天学习了下Mybatis的动态查询,然后接着上次的Demo改造了下实现表的关联查询. 话不多说,开始今天的小Demo 首先接着上次的项目 https ...

  5. SAML 2.0初始

    一.背景知识: SAML即安全断言标记语言,英文全称是Security Assertion Markup Language.它是一个基于XML的标准,用于在不同的安全域(security domain ...

  6. frist Django app — 一、 创建工程

    缘起 既然python都学了,学习python的时候感觉是相见恨晚,一种新的编程语言带给我一种新的思考问题的方式,为了巩固学过的东西并进一步学习python,就想学学Django,看看会不会带给我关于 ...

  7. python之路:列表及元组之定义

      python开发之路:列表及元组之定义 列表是以后用处较大的一个数据类型,这种数据类型可以存储按组分类的信息.好了,我不多说,开始讲了! 好了,现在我有个情景,我要存东汉时期(韩国,秦国,……)所 ...

  8. [原创] 扩展jquery-treegrid插件, 实现勾选功能和全删按钮.

    新上手一个项目, 因而正好想学习下bootstrap, 所以就采用asp.net mvc + bootstrap来做.  因为需要TreeGrid的控件, 本来想用easyUI.LingerUi.DW ...

  9. crontab,定时任务执行找不到库or shell可执行,crontab 定时任务下就不能执行,tensorflow,ImportError: libcuda.so.1: cannot open shared object file: No such file or directory

    在线上启动一个定时任务,但是起来查看,发现任务执行找不到库,报cuda错误: ImportError: libcuda.so.1: cannot open shared object file: No ...

  10. 跑步“无核心,不PB”

    核心力量不管是在跑步中,还是在生活中都有着重要的作用,核心能让你的身体机能更加强劲. 1.什么是核心肌群? 核心肌群就是指我们所说的躯干,包括脊柱.骨盆.及周围肌群. 核心肌群由腹直肌.腹横肌.腹斜肌 ...