INotifyPropertyChanged
我不是針對誰,我是說在座的各位
相信所有學wpf的,都寫過類似下面的程式碼:
實現INotifyPropertyChanged
public class MainViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
呼叫
private string _userName = string.Empty;
/// <summary>
/// 使用者名稱
/// </summary>
public string UserName
{
get => _userName;
set
{
_userName = value;
OnPropertyChanged();
}
}
當屬性多起來時,這就很煩人了····
於是乎,我們的PropertyChanged.Fody
就登場了
通過nuget安裝PropertyChanged.Fody
這是一個附加元件庫。我們可以通過nuget安裝,也可以通過在程式包管理控制檯輸入以下內容:
PM> Install-Package Fody
PM> Install-Package PropertyChanged.Fody
手動新增FodyWeavers.xml檔案
安裝完成後,我們需要手動新增名為FodyWeavers.xml的檔案,右鍵專案新增項選擇xml檔案即可。
注:該檔案是Fody配置檔案,更多資訊請參考配置
如果僅僅實現通知,我們只需要在檔案內新增一下內容
<Weavers>
<PropertyChanged/>
</Weavers>
完成以上操作後,所有實現 INotifyPropertyChanged
的類都將通知程式碼注入到屬性設定器中。
例如:
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName => $"{GivenNames} {FamilyName}";
}
在編譯後就會成為:
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(允許注入指向不同屬性的通知程式碼。)
我們只需要在屬性上打上要通知的屬性即可。
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(不要通知我)
我們也可以標記某屬性更新時不需要通知。
public class Person : INotifyPropertyChanged
{
public string GivenName { get; set; }
[DoNotNotify]
public string FamilyName { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
DependsOnAttribute(注入此屬性以便在設定依賴屬性時得到通知。)
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
技術交流Q群: 1012481075 群內有各種流行書籍資料
文章後續會在公眾號更新,微信搜尋 OneByOneDotNet 即可關注。
你的一分鼓勵,我的十分動力,點贊免費,感恩回饋。喜歡就點贊評論吧,雙擊66~