在WPF中,当我们要使用MVVM的方式绑定一个普通对象的属性时,界面上往往需要获取到属性变更的通知,

    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));
            }
        }
    }

这么做有一个比较大的隐患,那就是用了字符串的硬编码的方式传递了属性名称,一旦拼写错误或因为重构代码忘记去更新这个字符串时,这样就会导致界面上得不到更新。(本身硬编码的方式来保证两者的一致性就是不靠谱的行为)

虽然这本身并不是问题,但却不是很好的实践。也有人通过一些手段来解决这个问题,有的是通过表达式树,还有的通过Attribute注入的方式。

从性能上来讲,注入是一个比较好的方式,但往往引入了比较复杂的框架。实际上,在C# 5.0中就引入了一个调用方信息的语法方便我们获取调用方的函数名称和位置,通过它可以非常简单快捷的解决上面的这个问题:

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

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

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

代码很简单,这里就不多介绍了。

更进一步

有的时候,为了减少通知的频率,往往会把通知写出如下形式:

    private
int number;
    public
int Number
    {
        get { return number; }
        set

        {
            if (number == value)
                return;

            number = value;
            OnPropertyChanged();
        }
    }

    private
string text;
    public
string Text
    {
        get { return text; }
        set

        {
            if (text == value)
                return;

            text = value;
            OnPropertyChanged();
        }
    }

这种写法非常单调,并且在属性多的时候代码就显得很累赘了。这里我就写了一个通用点的函数把他们统一起来,下次就可以直接用了。

    private
int number;
    public
int Number
    {
        get { return number; }
        set { UpdateProper(ref number, value); }
    }

    private
string text;
    public
string Text
    {
        get { return text; }
        set { UpdateProper(ref text, value); }
    }

    protected
void UpdateProper<T>(ref T properValue, T newValue, [CallerMemberName] string properName = "")
    {
        if (object.Equals(properValue, newValue))
            return;

        properValue = newValue;
        OnPropertyChanged(properName);
    }

由于C#的语法限制,不能在类外部调用event,因此不能写成扩展方法,这里就简单的写成一个对象,下次就直接照着改好了:

    class
NotifyObject : INotifyPropertyChanged
    {
        private
int number;
        public
int Number
        {
            get { return number; }
            set { UpdateProper(ref number, value); }
        }

        private
string text;
        public
string Text
        {
            get { return text; }
            set { UpdateProper(ref text, value); }
        }

        protected
void UpdateProper<T>(ref T properValue, T newValue, [CallerMemberName] string properName = "")
        {
            if (object.Equals(properValue, newValue))
                return;

            properValue = newValue;
            OnPropertyChanged(properName);
        }

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

使用CallerMemberName简化InotifyPropertyChanged的实现的更多相关文章

  1. [转]使用CallerMemberName简化InotifyPropertyChanged的实现

    原文:https://www.cnblogs.com/TianFang/p/3381484.html 在WPF中,当我们要使用MVVM的方式绑定一个普通对象的属性时,界面上往往需要获取到属性变更的通知 ...

  2. C# 特性学习之一、CallerMemberName、CallerFilePath和CallerLineNumber

    在开发中经常会写个公有静态类记录日志,如下: /// <summary> /// Writes the error. /// </summary> /// <param ...

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

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

  4. 转载:如何优雅的实现INotifyPropertyChanged接口

    转载来源:http://www.cnblogs.com/TianFang/p/6240933.html 如何优雅的实现INotifyPropertyChanged接口 INotifyPropertyC ...

  5. C# 5.0中使用CallerMemberName、CallerFilePath和CallerLineNumber获取代码的调用方信息(转载)

    很多时候,我们需要在运行过程中记录一些调测的日志信息,如下所示: public void DoProcessing() { TraceMessage("DoProcessing()被XXX调 ...

  6. C# 各版本新特性

    C# 2.0 泛型(Generics) 泛型是CLR 2.0中引入的最重要的新特性,使得可以在类.方法中对使用的类型进行参数化. 例如,这里定义了一个泛型类: class MyCollection&l ...

  7. C# 5.0中新增特性

    C# 5.0随着VisualStudio 2012一起正式发布了,让我们来看看C#5.0中增加了哪些功能. 1. 异步编程 在.Net 4.5中,通过async和await两个关键字,引入了一种新的基 ...

  8. C# 语言历史版本特性(C# 1.0到C# 7.1汇总更新) C#各版本新特性 C#版本和.NET版本以及VS版本的对应关系

    C# 语言历史版本特性(C# 1.0到C# 7.1汇总更新) 2017年08月06日 11:53:13 阅读数:6705 历史版本 C#作为微软2000年以后.NET平台开发的当家语言,发展至今具有1 ...

  9. C# 5.0新加特性

    1. 异步编程 在.Net 4.5中,通过async和await两个关键字,引入了一种新的基于任务的异步编程模型(TAP).在这种方式下,可以通过类似同步方式编写异步代码,极大简化了异步编程模型.如下 ...

随机推荐

  1. 在cocos2dx和unity3d之间选择

    人生最纠结的事,莫过于有选择………… cocos2dx和unity3d从某种意义上讲,都很不错.但当面对特定需求以及团队情况的时候,总是能分出高下的. 假设,目标游戏是一款类似 刀塔传奇 的游戏 我们 ...

  2. [我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之纹理Textures

    [我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之纹理Textures 本篇分享一下第6个已完工的视频,即<beginner Graphics ...

  3. paip.解决access出现 -2147467259 无效的参数量

    paip.解决access出现 -2147467259   无效的参数量 作者Attilax  艾龙,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http: ...

  4. 高并发、海量数据处理尽量少使用using也能提升效率

    请看下面两段: 第一种方式: MemoryStream stream = new MemoryStream(); string text = "aasasdfasdfad;sas;fkqew ...

  5. LigerUI Tree

    <!DOCTYPE html> <%@ page language="java" contentType="text/html; charset=utf ...

  6. angularJS之事件处理

    angularJS的事件不像js一样,会默认有冒泡和捕获,还有angularJS之间的同名控制器之间,也只是同名, 不会让他们关联起来,就是这个名字的控制器的数据的改变不会影响到另一个同名的控制器. ...

  7. 查看Wait type

    Wait 能够指示系统存在的bottlenect 或 hot spot,再通过这些wait反馈的信息,对系统hardwar进行升级或对query 进行性能优化. 一,查看 Wait 统计信息 1,sy ...

  8. Github快速入门手册

    最近在试用Github,开源的思想也让人觉得把一些经验分享出来是非常好的事情.附件是doc文件,如有需要请注意查收.希望能对你有帮助. GITHUB基于互联网的版本控制快速入门手册 如有不妥,欢迎指正 ...

  9. javascript中数组和字符串的方法比较

    × 目录 [1]可索引 [2]转换 [3]拼接[4]创建[5]位置 前面的话 字符串和数组有很多的相同之处,它们的方法众多,且相似度很高:但它们又有不同之处,字符串是不可变值,于是可以把其看作只读的数 ...

  10. mysqll底层分享(一):MySQL索引背后的数据结构及算法原理

    http://www.uml.org.cn/sjjm/201107145.asp#nav-2 http://tech.it168.com/a2011/0711/1216/000001216087_al ...