WPF之依赖属性和附加属性
???????參考資料:
?????? 一站式WPF--依賴屬性(DependencyProperty)一
?????? 一站式WPF--依賴屬性(DependencyProperty)二
??????? 依賴屬性之我見:
這兩篇文章介紹的了依賴屬性的本質和由來,挺清晰的。
自我理解:依賴屬性,說明有兩個關系,依賴和屬性。
依賴的由來:
在面向對象的世界里,屬性大量存在,比如Button,就大約定義了70-80個屬性來描述其狀態。那么屬性的不足又在哪里呢?
當然,所謂的不足,要針對具體環境來說。拿Button來講,它的繼承樹是Button->ButtonBase->ContentControl->Control->FrameworkElement->UIElement->Visual->DependencyObject->…
每次繼承,父類的私有字段都被繼承下來。當然,這個繼承是有意思的,不過以Button來說,大多數屬性并沒有被修改,仍然保持著父類定義時的默認值。通常情況,在整個Button對象的生命周期里,也只有少部分屬性被修改,大多數屬性一直保持著初始值。每個字段,都需要占用4K等不等的內存,這里,就出現了期望可以優化的地方:
- 因繼承而帶來的對象膨脹。每次繼承,父類的字段都被繼承,這樣,繼承樹的低端對象不可避免的膨脹。????
- 大多數字段并沒有被修改,一直保持著構造時的默認值,可否把這些字段從對象中剝離開來,減少對象的體積
?????? 有了以上的背景,依賴就出現了,微軟設計了DependencyProperty類,?里面有著 public static DependencyProperty Register(string name, Type propertyType, Type ownerType, object defaultValue)方法來注冊屬性。然后又定義了一個DependencyObject的基類來消費這個屬性。這樣繼承自DenpendencyObject的類就可以注冊自己的依賴屬性,屬性是自己注冊的,其實嚴格的說并不是自己的,所以節省了空間。注冊的屬性在DependencyProperty里面通過一個hash(?internal static Dictionary<object, DependencyProperty> RegisteredDps = new Dictionary<object, DependencyProperty>())來維護。注冊過的屬性都存在這個hash里面。自此依賴我感覺的由來就清楚了,不是自己的屬性,而是此屬性要依賴于DependencyProperty的。
?????? 依賴解釋好了,那屬性呢?其實屬性就是對外暴漏接口罷了,注冊依賴屬性后就是給依賴屬性賦值(set),或者問依賴屬性取值(get),這些操作封裝到了DependencyObject類里面,所有用過的屬性的值都通過?List<EffectiveValueEntry> _effectiveValues = new List<EffectiveValueEntry>()來存儲和維護。這樣就不會污染最初的默認value。這里也就實現了某個屬性變化的過程都可以DependencyObject里面的effectiveValues找到痕跡,這樣也就支持了動畫。獲取和賦值都是通過EffectiveValueEntry這個入口來獲得的。就此依賴屬性設計好了。
?????? 這樣的設計聽好了,但是我們想要求子類也有自己的默認屬性,比如很多控件都有Name屬性,但有時候并不希望大家的默認值是一樣的,但是有共用同一個DP。這該怎么解決呢?
???????要想支持不同的默認值,那么內部就要維護一個對應不同DependencyObjectType的一個List,可以根據傳入的DependencyObject的類型來讀取它對應的默認值。DP內需要維護一個自描述的List,按照微軟的命名規則,添加新的類型屬性元數據(PropertyMetadata)。其實在DependencyProperty里面添加了private List<PropertyMetadata> _metadataMap = new List<PropertyMetadata>();來維護元數據,實現對默認值的修改。
??????附加屬性之我見:說白了就是依賴屬性的改造,只是封裝不同,區別在于附加二字,其實就是有些對象不具備某些屬性,有些對象具備這些屬性,那么具備這些依賴屬性的對象就可以某些屬性附加到不具備這些屬性的對象上。比如人沒有年級,班級的屬性,而學校有年級班級的屬性,但是當人在學校學習的時候就具備了班級年級的屬性,這個時候學校這個對象就可以附加給人這個對象班級年級的屬性。這就是附加屬性。
??????回想下依賴屬性,依賴屬性是對一個對象來說的,這個對象可以注冊依賴屬性,以后這個對象就具備了這個屬性。而附加屬性是對兩個對象來說的,一個是附加對象,一個是被附加對象。是不是可以這樣理解,附加對象給被附加對象注冊了一個依賴屬性罷了。但這個依賴屬性依靠附加對象操作。自己的理解不知道正確與否。
往更深層次的,就看看開頭兩篇的博客吧。
轉載于:https://www.cnblogs.com/fuchongjundream/p/3892949.html
總結
以上是生活随笔為你收集整理的WPF之依赖属性和附加属性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c# AseConnection的类型初
- 下一篇: 64位windows 7下成功配置Tor