WPF 进阶 - Fody PropertyChanged

相信每一个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

用于跳过给定属性的相等性检查。

评论