Fody,告別煩人的INotifyPropertyChanged,最簡方式實現通知!
阿新 • • 發佈:2021-01-30
### INotifyPropertyChanged
#### 我不是針對誰,我是說在座的各位
相信所有學wpf的,都寫過類似下面的程式碼:
實現INotifyPropertyChanged
```csharp
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
```
呼叫
```csharp
private string _userName = string.Empty;
///
/// 使用者名稱
///
public string UserName
{
get => _userName;
set
{
_userName = value;
OnPropertyChanged();
}
}
```
當屬性多起來時,這就很煩人了····
於是乎,我們的`PropertyChanged.Fody`就登場了
### 通過nuget安裝PropertyChanged.Fody
這是一個附加元件庫。我們可以通過nuget安裝,也可以通過在程式包管理控制檯輸入以下內容:
```csharp
PM> Install-Package Fody
PM> Install-Package PropertyChanged.Fody
```
### 手動新增FodyWeavers.xml檔案
安裝完成後,我們需要**手動**新增名為**FodyWeavers.xml**的檔案,右鍵專案新增項選擇xml檔案即可。
注:該檔案是Fody配置檔案,更多資訊請[參考配置](https://github.com/Fody/Home/blob/master/pages/configuration.md)
如果僅僅實現通知,我們只需要在檔案內新增一下內容
```xml
```
完成以上操作後,所有實現 `INotifyPropertyChanged` 的類都將通知程式碼注入到屬性設定器中。
例如:
```csharp
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName => $"{GivenNames} {FamilyName}";
}
```
在編譯後就會成為:
```csharp
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
string givenNames;
public string GivenNames
{
get => givenNames;
set
{
if (value != givenNames)
{
givenNames = value;
OnPropertyChanged(InternalEventArgsCache.GivenNames);
OnPropertyChanged(InternalEventArgsCache.FullName);
}
}
}
string familyName;
public string FamilyName
{
get => familyName;
set
{
if (value != familyName)
{
familyName = value;
OnPropertyChanged(InternalEventArgsCache.FamilyName);
OnPropertyChanged(InternalEventArgsCache.FullName);
}
}
}
public string FullName => $"{GivenNames} {FamilyName}";
protected void OnPropertyChanged(PropertyChangedEventArgs eventArgs)
{
PropertyChanged?.Invoke(this, eventArgs);
}
}
internal static class InternalEventArgsCache
{
internal static PropertyChangedEventArgs FamilyName = new PropertyChangedEventArgs("FamilyName");
internal static PropertyChangedEventArgs FullName = new PropertyChangedEventArgs("FullName");
internal static PropertyChangedEventArgs GivenNames = new PropertyChangedEventArgs("GivenNames");
}
```
### 特性
我們自然有些特殊需求,例如我需要更新A屬性通知B屬性,需要某些屬性不通知等等需求。於是Fody給我們提供了標記特性。
### AlsoNotifyForAttribute(允許注入指向不同屬性的通知程式碼。)
我們只需要在屬性上打上要通知的屬性即可。
```csharp
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; }
}
```
### DoNotNotifyAttribute(不要通知我)
我們也可以標記某屬性更新時不需要通知。
```csharp
public class Person : INotifyPropertyChanged
{
public string GivenName { get; set; }
[DoNotNotify]
public string FamilyName { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
```
### DependsOnAttribute(注入此屬性以便在設定依賴屬性時得到通知。)
```csharp
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; }
}
```
## 後記
> **本人不是大佬,只是道路先行者,在落河後,向後來的人大喊一聲,這裡有坑,不要過來啊!**
>
> **縱然如此,依舊有人重複著落河,重複著吶喊······**
個人部落格網站 [Blog](https://onebyone.icu/) 技術交流Q群: **1012481075** 群內有各種流行書籍資料 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210130083841496.png#pic_center) 文章後續會在公眾號更新,微信搜尋 **OneByOneDotNet** 即可關注。 你的一分鼓勵,我的十分動力,點贊免費,感恩回饋。喜歡就點贊評論吧,雙擊66~
個人部落格網站 [Blog](https://onebyone.icu/) 技術交流Q群: **1012481075** 群內有各種流行書籍資料 ![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20210130083841496.png#pic_center) 文章後續會在公眾號更新,微信搜尋 **OneByOneDotNet** 即可關注。 你的一分鼓勵,我的十分動力,點贊免費,感恩回饋。喜歡就點贊評論吧,雙擊66~