前一篇 簡單的介紹了Fody/PropertyChanged的使用方法, 這一篇,我們詳細介紹它的一些比較重要的特性和規則 1. Attributes 通過在類或屬性上標記這些特性,可以在編譯代碼時,註入特定的功能 ImplementPropertyChangedAttribute 為類標記此特性, ...
前一篇 簡單的介紹了Fody/PropertyChanged的使用方法, 這一篇,我們詳細介紹它的一些比較重要的特性和規則
1. Attributes
通過在類或屬性上標記這些特性,可以在編譯代碼時,註入特定的功能
ImplementPropertyChangedAttribute
為類標記此特性,可以實現INotifyPropertyChanged介面
[ImplementPropertyChanged]
public class Person
{
public string Name { get; set; }
}
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; }
}
在GivenName或FamilyName變化時,會同時也通知FullName的變化
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; }
}
DoNotSetChangedAttribute
通過約定,在實現的類里,如果有一個屬性是IsChanged
public bool IsChanged { get; set; }
在其它類發生變化時,此類的值會自動被設置為True,
如果希望在某個屬性變化時,不響應此規則,可以將屬性標記為DoNotSetChangedAttribute
public class Person: INotifyPropertyChanged
{
[DoNotSetChanged]
public string FullName { get; set; }
public bool IsChanged { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
在FullName變化里,不會將IsChanged設置為True
DoNotCheckEqualityAttribute
預設情況下,所有註入的變化響應,都會檢查是否相等,如果相等,則不會進行通知;但在某些時候,我們也許需要無論是否相等都進行通知,這個時候,可以在屬性上標記DoNotCheckEqualityAttribute以跳過是否相等的檢查
public class Person: INotifyPropertyChanged
{
[DoNotCheckEquality]
public string FullName { get; set; }
public bool IsChanged { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
這樣,在給FullName賦值時,無論是否和之前的值相等,都會進行通知。
2. BeforeAfter
有時候,我們需要在值發生變化時,訪問變化之前和之後的值,比如做驗證時,我們可以通過加入下麵的方法實現:
public void OnPropertyChanged(string propertyName, object before, object after)
比如,我們寫的代碼:
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Name { get; set; }
public void OnPropertyChanged(string propertyName, object before, object after)
{
//Perform property validation
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
在編譯時,對應的代碼為:
public class Person : INotifyPropertyChanged
{
private string name;
public event PropertyChangedEventHandler PropertyChanged;
public string Name
{
get { return name; }
set
{
object before = Name;
name = value;
OnPropertyChanged("Name", before, Name);
}
}
public void OnPropertyChanged(string propertyName, object before, object after)
{
//Perform property validation
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
3. EqualityChecking
在設置屬性的值之前,會進行是否相等的檢查:
public string Property1
{
get
{
return property1;
}
set
{
if (!String.Equals(property1, value))
{
property1 = value;
OnPropertyChanged("Property1");
}
}
}
用於檢查是否相等的方法依賴於屬性的數據類型,按照下麵的順序或規則進行比較:
- 如果類型是Nullable,則使用 Nullable.Equals(T?,T?)方法比較
- 如果類型包含有靜態的方法Equals,則使用靜態的方法對比兩個參數
- 如果類型有==方法,則使用==比較參數
- 使用Object.Equals(object,object)比較
4.實現IsChanged標誌
在上面我們已經簡單的介紹了IsChanged屬性,具體的實現代碼如下:
- 書寫的代碼
public class Person : INotifyPropertyChanged
{
public string Name { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public bool IsChanged { get; set; }
}
- 編譯對應的代碼 (省略比較的代碼)
public class Person : INotifyPropertyChanged
{
string name;
bool isChanged;
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public string Name
{
get { return name; }
set
{
name = value;
IsChanged = true;
OnPropertyChanged("Name");
}
}
public bool IsChanged
{
get { return isChanged; }
set
{
isChanged = value;
OnPropertyChanged("IsChanged");
}
}
}
這樣,在Name設置新值後,IsChanged屬性會被設置為True
當然,在代碼邏輯中,在適當的時候需要手動將IsChanged設置為false
還有一些配置和規則,可以參見https://github.com/Fody/PropertyChanged/wiki