软件编程
位置:首页>> 软件编程>> C#编程>> WPF中使用CallerMemberName简化InotifyPropertyChanged的实现

WPF中使用CallerMemberName简化InotifyPropertyChanged的实现

作者:天方  发布时间:2023-05-08 16:27:07 

标签: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));
           }
       }
   }

来源:https://www.cnblogs.com/TianFang/p/3381484.html

0
投稿

猜你喜欢

  • 相对布局要比前面讲的线性布局和表格布局要灵活一些,所以平常用得也是比较多的。相对布局控件的位置是与其周围控件的位置相关的,从名字可以看出来,
  • 前言坚持是一件比较难的事,坚持并不是自欺欺人的一种自我麻痹和安慰,也不是做给被人的,我觉得,坚持的本质并没有带着过多的功利主义,如果满是功利
  • C# 中没有四舍五入函数,程序语言都没有四舍五入函数,因为四舍五入算法不科学,国际通行的是 Banker 舍入法Bankers roundi
  • 前言socket是软件之间通讯最常用的一种方式。c#实现socket通讯有很多中方法,其中效率最高就是异步通讯。异步通讯实际是利用windo
  • 1.在C#中,类名首字母需大写。如:class Student2.在C#中Main()方法有四种形式:static void Main(st
  • 本文实例为大家分享了C#实现窗体抖动的具体代码,供大家参考,具体内容如下原理:围绕中心点运动一圈方法一:通过线程实现需求:需要using S
  • 在C# winform应用程序中,用以下代码可以进行一些内存使用的优化using System;using System.Diagnosti
  • 一、创建项目创建一个简单的Java项目,其中Main.java为主函数,包含main方法:二、完成JAR配置进入File->Proje
  • 一、this 关键字的使用1. 概述this是什么?在Java中,this关键字比较难理解,它的作用和其词义很接近,表示&ldquo
  • 前言:本人目前从事java开发,但同时也在学习各种前端技术,下面是我做的一个前后端分离项目的一个小案例,不足之处请多多指教1. 项目技术选型
  • 前言本文主要给大家介绍了关于C#连接FTP时路径问题的相关内容,分享出来供大家参考学习,话不多说,来一起看看详细的介绍:今天在开发项目时,需
  • 1 前言许多语言,例如 Perl ,Python 和 Ruby ,都有集合的本地支持。有些语言(例如Python)甚至将基本集合组件(列表,
  • 下载和上传附件、发送短信和发送邮件,都算是程序中很常用的功能,之前记录了文件的上传和下载还有发送短信,由于最近比较忙,邮件发送的功能就没有时
  • 上周五东西都收拾好了,然后被叫住加班,直接搞到凌晨一两点,原因是另一个项目的性能出了点问题。为此我抓包写了一下主业务流的接口,涉及到文件上传
  • Rxjava功能个人感觉很好用,里面的一些操作符很方便,Rxjava有:被观察者,观察者,订阅者,被观察者通过订阅者订阅观察者,从而实现观察
  • 当前,JVM生态圈主要的三大构建工具:Apache Ant(带着Ivy)MavenGradle对于初学者,Ant是最清晰的,只要读懂Xml配
  • 目录前言基础组件工作流程初步使用详细流程获取 MapperProxy 对象缓存执行方法构造参数获取需要执行的 SQL 对象执行 SQL 语句
  • 如果需要处理的数字有许多位,就可以使用BitArray类和BitVector32结构。BitArray类位于System.Collectio
  • 简介Spring Security 是为了基于Spring的应用程序提供的声明式安全保护的安全性框架。Spring Security 提供了
  • 一、why(为什么要用Hibernate缓存?)Hibernate是一个持久层框架,经常访问物理数据库。为了降低应用程序对物理数据源访问的频
手机版 软件编程 asp之家 www.aspxhome.com