標籤:not 技術 validate bsp 註冊 代碼 wpf 意思 關於
三個回調對應相依性屬性的驗證過程,改變過程和強制轉換過程。
class Dobj : DependencyObject{ //相依性屬性封裝 public int MyProperty { get { return (int)GetValue(MyPropertyProperty); } set { SetValue(MyPropertyProperty, value); } } //註冊相依性屬性 //注意相依性屬性預設值是:71 public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register("MyProperty", typeof(int), typeof(Dobj), new PropertyMetadata(71, PropertyChanged, CoerceValue), ValidateValue); //屬性改變 static void PropertyChanged(DependencyObject dobj, DependencyPropertyChangedEventArgs e) { Debug.WriteLine(String.Format("PropertyChanged - 屬性:{0} 新值:{1} 舊值:{2}", e.Property.Name, e.NewValue, e.OldValue)); } //強制轉換 static object CoerceValue(DependencyObject dobj, object newValue) { Debug.WriteLine(String.Format("CoerceValue - {0}", newValue)); return newValue; } //驗證 static bool ValidateValue(object obj) { Debug.WriteLine(String.Format("ValidateValue - {0}", obj)); return true; }}
當僅僅定義一個新對象時:
var dobj = new Dobj();
調試下輸出:
ValidateValue - 71ValidateValue - 71
驗證過程被執行了兩次,我不知道為什麼這樣。
接著修改這個對象的屬性。
var dobj = new Dobj();dobj.MyProperty = 999;
輸出:
ValidateValue - 71ValidateValue - 71ValidateValue - 999CoerceValue - 999PropertyChanged - 屬性:MyProperty 新值:999 舊值:71
預設值被驗證了兩遍,接著驗證新值,強制轉換,最後屬性改變回調。
接下來修改一下驗證回調,把傳回值改為false。
//驗證static bool ValidateValue(object obj){ Debug.WriteLine(String.Format("ValidateValue - {0}", obj)); if ((int)obj == 999) return false; return true;}
指派陳述式(SetValue方法)會拋出ArgumentException異常,訊息:’999′ is not a valid value for property ‘MyProperty’.(999並不是MyProperty屬性的合法值)。
下面要做到內容是建立一個當前依賴對象的繼承類,並改寫父類相依性屬性的中繼資料。
代碼:
//繼承原來的依賴對象class SuperDobj : Dobj{ static SuperDobj() { //改寫父類相依性屬性的中繼資料,預設值改成81 Dobj.MyPropertyProperty.OverrideMetadata(typeof(SuperDobj), new PropertyMetadata(81, PropertyChanged, CoerceValue)); } //屬性改變 static void PropertyChanged(DependencyObject dobj, DependencyPropertyChangedEventArgs e) { Debug.WriteLine(String.Format("SuperDobj.PropertyChanged - 屬性:{0} 新值:{1} 舊值:{2}", e.Property.Name, e.NewValue, e.OldValue)); } //強制轉換 static object CoerceValue(DependencyObject dobj, object newValue) { Debug.WriteLine(String.Format("SuperDobj.CoerceValue - {0}", newValue)); if ((int)newValue == 999) throw new Exception("test"); return newValue; }}
還是像剛才,先定義一個對象:
var superdobj = new SuperDobj();
輸出:
ValidateValue - 71ValidateValue - 71ValidateValue – 81
父類和子類的驗證都要執行一遍。
接著設定子類的相依性屬性:
var superdobj = new SuperDobj();superdobj.MyProperty = 999;
輸出:
ValidateValue - 71ValidateValue - 71ValidateValue - 81ValidateValue - 999SuperDobj.CoerceValue - 999PropertyChanged - 屬性:MyProperty 新值:999 舊值:81SuperDobj.PropertyChanged - 屬性:MyProperty 新值:999 舊值:81
這個結果很有意思。
看來子類和父類的驗證和屬性改變回調都會依次被調用,但是強制轉換隻調用子類的。
事實上屬性中繼資料此時會調用PropertyMetadata.Merge方法來合并多個屬性中繼資料。可以參考MSDN:http://msdn.microsoft.com/zh-cn/library/system.windows.propertymetadata.merge.aspx
原文地址:https://www.mgenware.com/blog/?p=188
【轉】【WPF】關於相依性屬性的ValidateValueCallback,PropertyChangedCallback和CoerceValueCallback的執行順序