相信每一个WPF开发工程师都会遇到这样一个问题,将业务转换成业务模型(Model)以后,就需要用相应的视图(VIEW)和视图模型(ViewModel)展示和交互,那么MVVM模式下就必然要做一个头疼的事情,那就是封装响应变化通知的CLR属性,顶级接口为:INotifyPropertyChanged
我们先看如何自己实现一个INotifyPropertyChanged的通知事件
1 2 3 4 5 6 7 8 9 10 11 12
| public class MainViewModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }
|
所有需要通知UI的CLR属性都需要响应这个方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| private string _appName; public string AppName { get { return _appName; } set { if (_appName == value) return; _appName = value; OnPropertyChanged(nameof(AppName)); } }
|
这样的写法,一个两个属性还好,在有很多属性的情况下,就显得有一些繁杂,今天要介绍一款开源的工具就是为了解决这个问题。
Fody PropertyChanged
使用方法:
使用方法
通过Nuget安装
PM> Install-Package PropertyChanged.Fody
安装完成后,会在项目中,添加FodyWeavers.xml文件,这是Fody的配置文件,详细可以参考 Fody
1 2 3 4
| <?xml version="1.0" encoding="utf-8"?> <Weavers> <PropertyChanged /> </Weavers>
|
说明
项目中所有标记有[AddINotifyPropertyChangedInterface]特性,或者实现了INotifyPropertyChanged的类,都将自动在其属性中实现通知相关的代码,除非属性被显示标记为不通知
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| [AddINotifyPropertyChangedInterface] public class Person { public string GivenNames { get; set; } public string FamilyName { get; set; }
public string FullName { get { return string.Format("{0} {1}", GivenNames, FamilyName); } } }
|
特性说明:
1.AlsoNotifyForAttribute
允许注入指向不同属性的通知代码。
例如
1 2 3 4 5 6 7 8 9 10 11 12
| 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; } }
|
2.DoNotNotifyAttribute
使用此属性可以从注入通知中排除属性或类型。
例如
1 2 3 4 5 6 7
| public class Person : INotifyPropertyChanged { public string GivenName { get; set; } [DoNotNotify] public string FamilyName { get; set; } public event PropertyChangedEventHandler PropertyChanged; }
|
3.DependsOnAttribute
注入此属性以在设置依赖属性时通知。
例如
1 2 3 4 5 6 7 8 9 10 11
| 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; } }
|
4.DoNotSetChangedAttribute
用于忽略IsChanged给定的属性。
例如IsChanged,FullName设置时不会调用以下示例。
1 2 3 4 5 6 7 8
| public class Person: INotifyPropertyChanged { [DoNotSetChanged] public string FullName { get; set; } public bool IsChanged { get; set; }
public event PropertyChangedEventHandler PropertyChanged; }
|
5.DoNotCheckEqualityAttribute
用于跳过给定属性的相等性检查。