原文:https://www.cnblogs.com/TianFang/p/3381484.html

在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的实现

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

  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. 软工读书笔记 week 9 ——《构建之法》

    软工读书笔记  week 9                 ——<构建之法> 最近的三周我们正式开始我们的项目.然后我也把<构建之法>中的相关章节再拿出来读了一番.以下是一些 ...

  2. LeetCode 之二叉树中序遍历(使用栈实现)

    1.题目描述 2.使用栈实现难度大于使用递归实现 3.代码 vector<int> inorderTraversal(TreeNode* root) { // 非递归实现,借助栈 vect ...

  3. 通过office365门户修改邮箱大小限制

    1. 使用管理员账号登陆中国区office365管理中心 https://login.partner.microsoftonline.cn/logout.srf 2. 进入管理员中心 3. 进入管理中 ...

  4. asp.net --- Menu控件\CSS 和样式

    几乎 Menu 控件外观的各个方面都可以使用 Menu 控件的属性或级联样式表 (CSS) 来管理.通过了解哪些属性控制呈现的哪些方面,可以定制菜单的外观.本主题介绍由 Menu 控件公开的样式类型, ...

  5. [控件] ChangeColorLabel

    ChangeColorLabel 效果 源码 // // ChangeColorLabel.h // YXMWeather // // Created by XianMingYou on 15/6/2 ...

  6. swift关于UIView设置frame值的extension

    swift关于UIView设置frame值的extension 使用 说明 1. 使用如上图,很简单,不再赘述 2. 在extension给添加的计算属性提供getter,setter方法即可 源码 ...

  7. Linux alias命令详解

    alias:内置命令(没有路径),设置命令的别名,保护系统,方便 unalias:别名取消 常用的命令展示 临时设置 alias cp='cp –i' unalias cp      取消系统的别命令 ...

  8. tomcat7换端口号调试

    1.C:\tomcat\conf\server.xml中修改端口号 2.C:\tomcat\bin\startup.bat批处理文件启动tomcat 3.用ctrl+c结束批处理文件 4.调试结束

  9. C++ Circle

    作业链接 https://github.com/How-Come/object-oriented/tree/master/Circle

  10. Extjs TreePanel API详解

    转自:http://web.qhwins.com/CSS-JS-XML/2011091312092944999107.html config定义{ animate : Boolean, contain ...