WPF开发中PropertyChanged.Fody的使用
现在基本上每一个项目都会使用PropertyChanged.Fody,用了以后,代码确实简洁清爽了很多。
安装
Install-Package PropertyChanged.Fody
继承INotifyPropertyChanged接口
安装了PropertyChanged.Fody以后,默认会为带INotifyPropertyChanged接口的类里面的属性都加上变更通知功能。
public class Person : INotifyPropertyChanged { [AlsoNotifyFor("FullName")] public string GivenName { get; set; } [AlsoNotifyFor("FullName")] public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; public string FullName { get; set; } }
因为我平常开发的时候基本上都会使用Prism,所以一般我会把类定义下继承Prism的BindableBase类,如下:
public class Person : BindableBase { [AlsoNotifyFor("FullName")] public string GivenName { get; set; } [AlsoNotifyFor("FullName")] public string FamilyName { get; set; } public string FullName { get; set; } }
因为BindableBase类会实现INotifyPropertyChanged接口。
ImplementPropertyChanged
也通过给没有INotifyPropertyChanged接口的类,增加ImplementPropertyChanged附加属性来实现通知的功能。但好像不推荐,官方推荐用上面的方式。
[ImplementPropertyChanged] public class Person { public string Name { get; set; } }
DoNotNotify
不希望通知的属性可以加上[DoNotNotify]的附加属性。
public class Person : INotifyPropertyChanged { public string GivenName { get; set; } [DoNotNotify] public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; }
AlsoNotifyFor
如果想要某个属性变化了以后,同时通知其它属性,可以添加AlsoNotifyFor附加属性。
public class Person : INotifyPropertyChanged { [AlsoNotifyFor("FullName")] public string GivenName { get; set; } [AlsoNotifyFor("FullName")] public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; public string FullName { get; set; } }
在GivenName或FamilyName变化时,会同时也通知FullName的变化。
DependsOn
如果属性之间有联动的,也可以通过添加DependsOn附加属性来实现同步通知的功能。
public class Person : INotifyPropertyChanged { public string GivenName { get; set; } public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; [DependsOn("GivenName","FamilyName")] public string FullName { get; set; } }
这样只要GivenName和FamilyName属性发生变化了,也会通知界面FullName属性变更了。
当然也可以使用下面的nameof的方式。
public class Person : INotifyPropertyChanged { public string GivenName { get; set; } public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; [DependsOn(nameof(GivenName), nameof(FamilyName))] public string FullName { get; set; } }
IsChanged
如果类里面添加了IsChanged属性,但只要类里的属性有变化,IsChanged会自动被设为true。
public class Person: INotifyPropertyChanged { public string FullName { get; set; } public bool IsChanged { get; set; } public event PropertyChangedEventHandler PropertyChanged; }
DoNotSetChanged
如果希望某个属性变化的时候,不修改IsChanged的值,可以添加DoNotSetChanged的附加属性。
public class Person: INotifyPropertyChanged { public string GivenName { get; set; } public string FamilyName { get; set; } [DoNotSetChanged] public string FullName { get; set; } public bool IsChanged { get; set; } public event PropertyChangedEventHandler PropertyChanged; }
上面的代码,GivenName和FamilyName属性发生变化时,IsChanged的值会变为true。FullName属性变化时,IsChanged的值不会变。
DoNotCheckEquality
默认情况下,变化响应会先检查是否相等,如果相等,则不会进行通知。
如果需要不管相等不相等,都进行变更通知。则可以加上DoNotCheckEquality附加属性。
public class Person: INotifyPropertyChanged { [DoNotCheckEquality] public string FullName { get; set; } public bool IsChanged { get; set; } public event PropertyChangedEventHandler PropertyChanged; }
这样,在给FullName赋值时,无论是否和之前的值相等,都会进行通知。
常见问题
1、编译时提示【Fody: The package reference for PropertyChanged.Fody does not contain PrivateAssets='All'】的错误
这个报错是指在使用Fody和PropertyChanged.Fody库时,包引用中缺少`PrivateAssets='All'`的设置。为了解决这个问题,可以按照以下步骤进行操作:
1. 打开你的项目文件(例如.csproj文件)。
2. 找到对应的`<PackageReference>`元素,它指向PropertyChanged.Fody库。
3. 在该元素内部添加`<PrivateAssets>all</PrivateAssets>`,确保设置正确。
<PackageReference Include="PropertyChanged.Fody"> <PrivateAssets>all</PrivateAssets> </PackageReference>
4. 保存并关闭项目文件。
5. 重新构建项目,检查报错是否解决。
通过添加`<PrivateAssets>all</PrivateAssets>`设置,你告诉MSBuild在构建项目时不包含这个包引用的任何私有资产。这可以防止这个包被传递到依赖项中,并解决了`PrivateAssets='All'`的缺失导致的报错。
如果问题仍然存在,可能需要检查Fody和PropertyChanged.Fody库的版本兼容性,并确保它们与你的项目和其他依赖项兼容。
参考网址
https://github.com/Fody/PropertyChanged
https://www.cnblogs.com/cqgis/p/6360231.html
https://www.cnblogs.com/cqgis/p/6360302.html