WPF插件之 - PropertyChanged.Fody使用详解
总目录
文章目录
总目录
一、PropertyChanged.Fody是什么?
二、PropertyChanged.Fody的安装
三、PropertyChanged.Fody的功能
1. 特性
1 实现属性通知的功能
2 通知其他属性
4 不进行属性通知
3 指定属性更改时将调用的方法
5 设置当前属性依赖的属性
6 不检查是否相等
7 DoNotSetChangedAttribute
2. 配置FodyWeavers.xml文件
1 EventInvokerNames
2 InjectOnPropertyNameChanged
3 CheckForEquality
结语
一、PropertyChanged.Fody是什么?
PropertyChanged.Fody 主要是实现了INotifyPropertyChanged 接口的,然后通过特性对外提供相关属性通知功能。
引用该插件能够使我们属性通知的代码更为简洁。
源码:https://github.com/Fody/PropertyChanged
如在阅读本文后,后续遇到文中没有提及的问题或知识点,可以查看源码说明文档
二、PropertyChanged.Fody的安装
1.首先添加PropertyChanged.Fody的Nuget程序包
如果通过程序包管理器控制台安装,则如下操作
先调出控制台,然后根据需求修改程序包源和需要安装程序包的项目
输入程序包的安装命令,即可完成程序包的安装
PM> Install-Package Fody
PM> Install-Package PropertyChanged.Fody
1
2
2.再者添加FodyWeavers.xml 文件
一般安装完PropertyChanged.Fody程序包后,会自动创建FodyWeavers.xml 文件;如果没有自动创建FodyWeavers.xml 文件,此时我们可以重新生成项目,然后项目生成时会自动在项目根目录下创建FodyWeavers.xml 文件,此时还没有包括在项目中,我们需要先显示所有文件,然后将FodyWeavers.xml 文件包含在项目中即可。如果以上操作均没有生成FodyWeavers.xml 文件,则自行在项目中创建FodyWeavers.xml 文件,然后在文件中,配置如下代码:
<Weavers>
<PropertyChanged/>
</Weavers>
1
2
3
三、PropertyChanged.Fody的功能
当我们介绍完安装完程序包后,下面就需介绍如何使用该程序包中提供的功能。
1. 特性
PropertyChanged.Fody的核心功能就是提供了一系列的特性供我们使用,通过给属性和类上标注特性,是我们的代码更加的简洁
1 实现属性通知的功能
通常我们自己手动实现INotifyPropertyChanged接口后,会需要将我们自己的ViewModel继承自实现类,然后在属性中调用方法来实现属性通知。如下示例中,ViewModelBase为自行实现INotifyPropertyChanged接口的实现类:
public class MainViewModel:ViewModelBase
{
private double _num;
public double Num
{
get { return _num; }
set { _num = value; OnPropertyChanged(); }
}
}
1
2
3
4
5
6
7
8
9
当我们使用了PropertyChanged.Fody插件后,可通过以下方式来实现一样的功能
方式1:直接将ViewModel的类继承自INotifyPropertyChanged类,所有实现INotifyPropertyChanged的类都将向属性设置器注入通知代码
方式2:在ViewModel的类上添加AddINotifyPropertyChangedInterface特性,旧版是添加ImplementPropertyChanged 特性,但该特性已弃用
方式1 示例代码:
public class MainViewModel : INotifyPropertyChanged
{
public double Num { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
1
2
3
4
5
6
方式2示例代码:
[AddINotifyPropertyChangedInterface]
public class MainViewModel
{
public double Num { get; set; }
}
1
2
3
4
5
以上两种方式作用是一样的,都可以实现属性通知,并且还可以使我们属性通知的代码量大大的减少,编码界面更为简洁清晰。
通过下图了解一下通过以上方式,实现属性通知后的反编译代码
下面我们通过一个完整的案例了解一下具体的使用,案例中实现Num1+Num2=Total:
反编译后的代码:
通过以上案例我们知道:
当我们在添加AddINotifyPropertyChangedInterface特性的类中,A属性引用了B和C属性,那么B和C属性代码中就会插入通知A属性更新的代码;如上面的案例中,Total属性中引用了Num1和Num2,反编译后Num1和Num2的属性访问器中就会添加<>OnPropertyChanged(<>PropertyChangedEventArgs.Total); 这样的一句代码,表示Num1和Num2属性更新后,不仅会通知自身,还会通知Total。
当属性中有了业务逻辑代码,则不会插入属性更新的代码,如上案例Total属性的get访问器中有了业务代码,那么Total将不具有属性更新通知的功能
注意:只有在类上标注AddINotifyPropertyChangedInterface特性或者实现INotifyPropertyChanged接口后,PropertyChanged.Fody中其他的特性才能生效,否则其他特性单独使用是无效的。
2 通知其他属性
通过AlsoNotifyFor特性,我们可以实现在通知自身属性的时候,通知其他的属性进行更新;
实现原理:也仅仅是使用了该特性后,set访问器中会自动插入对应属性的属性通知代码
通过下图的源代码和反编译代码对比图可以加以佐证:
另外建议使用nameof去配置需要 另外通知的属性名,不容易出现低级错误;再者可以通过逗号配置多个需要另外通知的属性。
[AddINotifyPropertyChangedInterface]
public class MainViewModel
{
[AlsoNotifyFor(nameof(Total),nameof(Num2))]
public double Num1 { get; set; }
public double Num2 { get; set; }
public double Total { get; set; }
}
1
2
3
4
5
6
7
8
4 不进行属性通知
如果ViewModel中的某一些属性,我们并不希望其具有属性通知的功能,可以使用DoNotNotify特性。
[AddINotifyPropertyChangedInterface]
public class MainViewModel
{
[DoNotNotify]
public double Num1 { get; set; }
public double Num2 { get; set; }
public double Total { get; set; }
}
1
2
3
4
5
6
7
8
3 指定属性更改时将调用的方法
默认情况下:如果有一个属性为Num,有一个方法为 OnNumChanged方法,那么在Num属性值更新的时候,就会执行OnNumChanged方法,只要是方法符合以上命名规则,就会自动生成调用代码。
[AddINotifyPropertyChangedInterface]
public class MainViewModel
{
//在Num1更新时,自动调用OnNum1Changed方法
public double Num1 { get; set; }
public double Num2 { get; set; }
public double Total { get; set; }
private void OnNum1Changed()
{
Total = Num1 + Num2;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
但是,如果我们向明确的指定属性更改时需要调用的方法,则需通过OnChangedMethod特性。
通过下图了解OnChangedMethod特性的原理,原理很简单就是在set访问器中调用特性中配置的方法。
[AddINotifyPropertyChangedInterface]
public class MainViewModel
{
[OnChangedMethod(nameof(OnNumChanged))]
public double Num1 { get; set; }
[OnChangedMethod(nameof(OnNumChanged))]
public double Num2 { get; set; }
public double Total { get; set; }
private void OnNumChanged()
{
Total = Num1 + Num2;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
以上案例表示当Num1和Num2 更新的时候,就执行OnNumChanged这个方法计算数字和。
5 设置当前属性依赖的属性
我们知道当我们给属性添加了AlsoNotifyFor特性的时候,可以实现在通知自身属性的时候,通知其他的属性进行更新;但是如果多个属性都通过AlsoNotifyFor指向的是同一个属性的时候,逐个添加不免有些麻烦;此时我们就可以使用DependsOn 特性,统一在最终指向的属性上,设置其依赖的属性即可。
[AddINotifyPropertyChangedInterface]
public class MainViewModel
{
public double Num1 { get; set; }
public double Num2 { get; set; }
[DependsOn(nameof(Num1),nameof(Num2))]
public double Total { get; set; }
}
1
2
3
4
5
6
7
8
9
6 不检查是否相等
默认情况下,所有属性通知中都会检查属性值是否相等,如果属性值相等,则不会进行通知;原理代码如下:
public string Property1
{
get
{
return property1;
}
set
{
if (!String.Equals(property1, value))
{
property1 = value;
OnPropertyChanged("Property1");
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
但在某些情况下,我们需要无论是否相等都会进行通知,这个时候,可以在属性上标记DoNotCheckEquality特性以跳过是否相等的检查。
[AddINotifyPropertyChangedInterface]
public class MainViewModel
{
[DoNotCheckEquality]
public double Num1 { get; set; }
public double Num2 { get; set; }
public double Total { get; set; }
}
1
2
3
4
5
6
7
8
9
当我们给属性加上DoNotCheckEquality特性的时候,就相当于给去掉了Object.Equals() 这个判断。
7 DoNotSetChangedAttribute
如果在添加了AddINotifyPropertyChangedInterface特性或者实现INotifyPropertyChanged接口的实现类中,有一个属性是IsChanged属性,那么默认情况下,当前类中的所有属性只要发生变化,都会将IsChanged 的属性值设置为True;
public bool IsChanged { get; set; }
1
如果希望在某个属性变化时,不设置IsChanged的属性值,可以给属性添加DoNotSetChanged特性,如下所示:
[AddINotifyPropertyChangedInterface]
public class MainViewModel
{
public bool IsChanged { get; set; }
public double Num1 { get; set; }
public double Num2 { get; set; }
[DoNotSetChanged]
public double Total { get; set; }
}
1
2
3
4
5
6
7
8
9
10
2. 配置FodyWeavers.xml文件
1 EventInvokerNames
该配置用于更改激发属性通知事件的方法名称,这是一个以逗号分隔形式接受多个值的字符串。默认值为:
<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<PropertyChanged EventInvokerNames="OnPropertyChanged, NotifyOfPropertyChange, RaisePropertyChanged, NotifyPropertyChanged, NotifyChanged"/>
</Weavers>
1
2
3
4
默认值覆盖了WPF中大多数的MVVM框架对于激发通知事件的方法命名,如Prism和MVVMLight 框架中使用的是RaisePropertyChanged,Caliburn Micro中使用的是NotifyOfPropertyChange。
如果需要指定激发属性通知事件方法的名称,则如下指定即可。(基本是使用默认配置的,因为默认值已经覆盖大多数的框架。)
<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<PropertyChanged EventInvokerNames="NotifyPropertyChanged"/>
</Weavers>
1
2
3
4
2 InjectOnPropertyNameChanged
用于控制是否启用On_PropertyName_Changed功能。默认值为true,启用该功能。
On_PropertyName_Changed 的功能就是:属性更改时执行对应名称的方法(如Num对应的OnNumChanged)以及OnChangedMethod特性所实现的功能
<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<PropertyChanged InjectOnPropertyNameChanged='false'/>
</Weavers>
1
2
3
4
3 CheckForEquality
用于控制是否应创建相等检查。如果为false,将对项目禁用相等检查。默认值为true,创建相等检查
<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<PropertyChanged CheckForEquality='false'/>
</Weavers>
1
2
3
4
结语
以上就是本文的内容,希望以上内容可以帮助到您,如文中有不对之处,还请批评指正。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_39847278/article/details/130658337
WPF插件之 - PropertyChanged.Fody使用详解的更多相关文章
- 提高Java代码质量的Eclipse插件之Checkstyle的使用详解
提高Java代码质量的Eclipse插件之Checkstyle的使用详解 CheckStyle是SourceForge下的一个项目,提供了一个帮助JAVA开发人员遵守某些编码规范的工具.它能够自动化代 ...
- 前端html、CSS快速编写代码插件-Emmet使用方法技巧详解
前端html.CSS快速编写代码插件-Emmet使用方法技巧详解 Emmet的前身是大名鼎鼎的Zen coding,如果你从事Web前端开发的话,对该插件一定不会陌生.它使用仿CSS选择器的语法来 ...
- Elasticsearch之sense插件安装之后的浏览详解
前提博客是 Elasticsearch之sense插件的安装(图文详解) 立马,可以看到 http://192.168.80.145:5601/app/sense 以后更新
- js插件---videojs中文文档详解
js插件---videojs中文文档详解 一.总结 一句话总结: js插件网上都有很多参考资料,使用起来也非常简单 二.lavarel中使用实例 <video id="example_ ...
- 时间插件--daterangepicker使用和配置详解
1.序言: daterangepicker是Bootstrap的一个时间组件,使用很方便 用于选择日期范围的JavaScript组件. 设计用于Bootstrap CSS框架. 它最初是为了改善报表而 ...
- 全网最详细的Sublime Text 3的安装Package Control插件管理包(图文详解)
不多说,直接上干货! 全网最详细的Windows里下载与安装Sublime Text *(图文详解) 全网最详细的Sublime Text 3的激活(图文详解) 全网最详细的Sublime Text ...
- 全网最详细的Sublime Text 3的插件官方网站(图文详解)
不多说,直接上干货! 全网最详细的Windows里下载与安装Sublime Text *(图文详解) 全网最详细的Sublime Text 3的激活(图文详解) 全网最详细的Sublime Text ...
- jquery图片切换插件jquery.cycle.js参数详解
转自:国人的力量 blog.163.com/xz551@126/blog/static/821257972012101541835491/ 自从使用了jquery.cycle.js,我觉得再也不用自己 ...
- Elasticsearch之shield(权限)插件安装之后的浏览详解
前期博客 Elasticsearch-2.4.3的3节点安装(多种方式图文详解)(含 head.kopf.marvel.shield和watcher插件安装和使用) 访问es:-u es_admin ...
- Elasticsearch之marvel(集群管理、监控)插件安装之后的浏览详解
前提 Elasticsearch之插件介绍及安装 https://i.cnblogs.com/posts?categoryid=950999&page=2 (强烈建议,从头开始看) 比如,我 ...
随机推荐
- SilentEye qsnctf wp
题目附件(注:文件名为Luminous.jpg) 根据题目提示,使用SilentEye工具 将图片使用SilentEye打开 使用左下角的Decode解密功能 猜测密码为文件名,输入并开始解密 将被加 ...
- 有用的JavaScript技巧
首次为变量赋值时务必使用var关键字 变量没有声明而直接赋值得话,默认会作为一个新的全局变量,要尽量避免使用全局变量. 使用===取代== ==和!=操作符会在需要的情况下自动转换数据类型.但===和 ...
- easyx的使用,图像插入(2.0)
本文从B站学习,借鉴,一些贴图素材借鉴游戏网图: 视频链接:图像输出_哔哩哔哩_bilibili 想使用图片,先用easyx提供的数据类型定义一个变量: 在对图片进行加载,差不多像是赋值,这个变量名相 ...
- 【笔记】Linux基础指令
Linux基础指令 cd 跳转文件夹 cd 到根目录 cd usr 到根目录下的usr目录 cd .. 到上一级目录 cd ~ 到home目录 cd - 到上次访问的目录 sh 执行sh命令 ls 查 ...
- HarmonyOS NEXT应用开发案例——二级联动
介绍 本示例主要介绍了List组件实现二级联动(Cascading List)的场景. 该场景多用于短视频中拍摄风格的选择.照片编辑时的场景的选择. 效果图预览 使用说明: 滑动二级列表侧控件,一级列 ...
- MaxCompute笛卡尔积逻辑的参数优化&复杂JOIN逻辑优化
简介: 这篇文章主要讲一个SQL优化反映的两个优化点.分别是: 一.笛卡尔积逻辑的参数优化. 二.一个复杂JOIN逻辑的优化思路. 1. 优化概述 最近协助一个项目做下优化任务的工作.因为主要数据都 ...
- 3 种发布策略,解决 K8s 中快速交付应用的难题
作者 | 郝树伟(流生)阿里云高级研发工程师 前言 软件技术更新换代很快,但我们追求的目标是一直不变的,那就是在安全稳定的前提下,增加应用的部署频率,缩短产品功能的迭代周期,这样的好处就是企业可以在更 ...
- LVGL scroll超出父界面不隐藏
问题 超出父界面不隐藏问题,即时使用了lv_obj_set_style_clip_corner()函数,也不起作用,如下图所示: 即使使用lv_obj_set_style_clip_corner(vi ...
- Ubuntu环境下docker每次都需要sudo的问题
1.添加 docker 用户组 sudo groupadd docker 可以通过 cat /etc/group 指令查看存在的用户组 2.将当前用户添加到 docker 组中 sudo gpassw ...
- CF1097C Yuhao and a Parenthesis
CF1097C Yuhao and a Parenthesis stl 乱搞做法,感觉比正解更直接. 每个字符串内部能匹配的尽可能匹配. 匹配完成后,检验剩余序列是否只含有 ( 或只含有 ) 或为空, ...