WPF中使用CallerMemberName简化InotifyPropertyChanged的实现

 更新时间:2022年06月20日 11:56:05   作者:天方  
这篇文章介绍了WPF中使用CallerMemberName简化InotifyPropertyChanged的实现,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

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

到此这篇关于WPF中使用CallerMemberName简化InotifyPropertyChanged的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#实现定义一个通用返回值

    C#实现定义一个通用返回值

    这篇文章主要介绍了C#如何实现自定义一个比较通用的返回值对象,然后使用泛型来传递需要return的数据。文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-09-09
  • C#仿QQ聊天窗口

    C#仿QQ聊天窗口

    这篇文章主要为大家详细介绍了C#仿QQ聊天窗口,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • C#生成带logo的二维码

    C#生成带logo的二维码

    带logo的二维码生成分为两步骤:首先根据输入的内容生成二维码图片,然后读取本地的logo图片,通过图片处理生成带logo的二维码。本文对此进行介绍,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • WinForm拖拽控件生成副本的解决方法

    WinForm拖拽控件生成副本的解决方法

    这篇文章主要介绍了WinForm拖拽控件生成副本的解决方法,对C#新手有一定的学习借鉴价值,需要的朋友可以参考下
    2014-08-08
  • C#中的委托Delegate

    C#中的委托Delegate

    这篇文章介绍了C#中的委托Delegate,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

    C#使用LINQ中Enumerable类方法的延迟与立即执行的控制

    这篇文章主要介绍了C#的LINQ查询中Enumerable类方法的延迟与立即执行,LINQ语言集成查询可以让C#和VB以查询数据库相同的方式操作内存数据,需要的朋友可以参考下
    2016-03-03
  • C# 字符串多行显示/文本换行以textbox为例讲解

    C# 字符串多行显示/文本换行以textbox为例讲解

    C# 字符串多行显示、文本换行以textbox为例讲为大家详细介绍并附演示效果图及演示代码,感兴趣的朋友可以了解下,或许对你学习字符串换行有所帮助
    2013-02-02
  • 详解C#批量插入数据到Sqlserver中的四种方式

    详解C#批量插入数据到Sqlserver中的四种方式

    本文主要讲解一下在Sqlserver中批量插入数据。文中大数据批量插入方式一和方式四尽量避免使用,而方式二和方式三都是非常高效的批量插入数据方式,需要的朋友可以看下
    2016-12-12
  • C#中匿名方法与委托的关系介绍

    C#中匿名方法与委托的关系介绍

    这篇文章介绍了C#中匿名方法与委托的关系,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • C#编程实现连接ACCESS数据库实例详解

    C#编程实现连接ACCESS数据库实例详解

    这篇文章主要介绍了C#编程实现连接ACCESS数据库的方法,以实例形式较为详细的分析了C#连接access数据库的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-11-11

最新评论