WPF入門教程系列十一——依賴屬性(一)

1、依賴屬性基本介紹 編程

  本篇開始學習WPF的另外一個重要內容依賴屬性。函數

     你們都知道WPF帶來了不少新的特性,其中一個就是引入了一種新的屬性機制——依賴屬性。依賴屬性出現的目的是用來實現WPF中的樣式、自動綁定及實現動畫等特性。依賴屬性的出現是WPF這種特殊的呈現原理派生出來的,與.NET普通屬性不一樣的是,依賴屬性的值是依靠多個提供程序來判斷的,而且其具備內建的傳遞變動通知的能力。學習

     依賴屬性基本應用在了WPF的全部須要設置屬性的元素。依賴屬性根據多個提供對象來決定它的值 (能夠是動畫、父類元素、綁定、樣式和模板等),同時這個值也能及時響應變化。動畫

     依賴屬性就是能夠本身沒有值,並可以經過Binding從數據源獲 取值(依賴在別人身上)的屬性。擁有依賴屬性的對象被稱爲「依賴對象」。依賴項屬性的重點在於「依賴」二字,既然是依賴了,也就是說:依賴項屬性的值的改變過程必定與其它對相關,不A依賴B就B依賴A,或者相互依賴。spa

 

     說白了,所謂依賴,主要應用在如下地方:雙向綁定

     一、雙向綁定。有了這個,依賴項屬性不用寫額的代碼,也不用實現什麼接口,它自己就俱備雙向綁定的特性,好比,我把員工對象的姓名綁定到搖文本框,一旦綁定,只要文本框中的值發生改變,依賴項屬性員工姓名也會跟着變化,反之亦然;orm

     二、觸發器。這個東西在WPF中很重要,好比,一個按鈕背景是紅色,我想讓它在鼠標停留在它上面是背景變成綠色,而鼠標一旦移開,按鈕恢復紅色。對象

若是在傳統的Windows編程中,你必定會想辦法弄一些事件,或者委託來處理,還要寫一堆代碼。告訴你,有了依賴項屬性,你將一行代碼都不用寫,全部的處理均由WPF屬性系統自動處理。而觸發器只是臨時改變屬性的值,當觸完成時,屬性值自動被「還原」。blog

     三、附加屬性。附加屬性也是依賴項屬性,它能夠把A類型的的某些屬性推遲到運行時根據B類型的具體狀況來進行設置,並且能夠同時被多個類型對象同時維護同一個屬性值,但每一個實例的屬性值是獨立的。繼承

     四、A屬性改變時,也同時改變其它屬性的值,如TogleButton按下的同時,彈出下拉框。

 

     與傳統的CLR屬性和麪向對象相比依賴屬性有不少新穎之處,其中包括:

      一、新功能的引入:加入了屬性變化通知,限制、驗證等等功能,這樣就可使咱們更方便的實現咱們的應用,同時也使代碼量大大減小了,許多以前不可能的功能均可以輕鬆的實現了。
      二、 節約內存:在WinForm等項目開發中,你會發現UI控件的屬性一般都是賦予的初始值,爲每個屬性存儲一個字段將是對內存的巨大浪費。WPF依賴屬性 容許對象在被建立的時候並不包含用於存儲數據的空間(即字段所佔用的空間)、只保留在須要用到數據的時候可以得到默認值。借用其它對象的數據或者實 時分配空間的能力----這種對象稱爲依賴對象而他這種實時獲取數據的能力則依靠依賴屬性來實現。在WPF開發中,必須使用依賴對象做爲依賴屬性的宿主, 使兩者結合起來,才能造成完整的Binding目標被數據所驅動。。
      三、支持多個提供對象:咱們能夠經過多種方式來設置依賴屬性的值。同時其內部能夠儲存多個值,配合Expression、Style、Animation等能夠給咱們帶來很強的開發體驗。
  在.NET當中,對於屬性是你們應該很熟悉,封裝類的字段,表示類的狀態,編譯後被轉化爲對應的get和set方法。屬性能夠被類或結構等使用。 一個簡單的屬性以下,也是咱們經常使用的寫法:

 

public class Student

    {

        string m_Name;

 

        public string Name

        {

            get { return m_Name; }

            set { m_Name = value; }

        }

        static Student()

        {

       

        }

 

 

    }

 

     依賴屬性與普通的.NET屬性的區別是普通的.NET屬性定義只須要定義其set和get區塊的賦值與設置。那麼依賴屬性應該怎麼定義呢?依賴屬性和屬性到底有什麼區別和聯繫呢?其實依賴屬性的實現也很簡單,按如下步驟作就能夠了:

     第一步: 讓本身的類繼承自 DependencyObject基類。在WPF中,幾乎全部的UI元素都繼承自DependencyObject,這個類封裝了對依賴屬性的存儲及 訪問等操做,使用靜態類型與依賴屬性的內部存儲機制相關。WPF處理依賴屬性再也不像普通.NET屬性那樣將屬性值存儲到一個私有變量中,而是使用一個字典 型的變量來存放用戶顯示設置的值。

     第二步:依賴屬性的定義必須使用 public static 聲明一個 DependencyProperty的變量,而且有一個Property做爲後綴,該變量纔是真正的依賴屬性 。例以下面的代碼定義了一個依賴屬性NameProperty:

 

 public static readonly DependencyProperty NameProperty;

 

     第三步:在靜態構造函數中向屬性系統註冊依賴屬性,並獲取對象引用。依賴屬性是經過調用DependencyProperty.Register靜態方法建立,該方法須要傳遞一個屬性 名稱,這個名稱很是重要,在定義控件Style和Template的時候,Setter的Property屬性填入的值就是註冊依賴屬性時使用的名稱。propertyType指明瞭依賴屬性實際的類型,ownerType指明瞭是哪一個類註冊了此依賴屬性,最後typeMetadata存放了一些依賴屬 性的元信息,包括依賴屬性使用的默認值,還有屬性值發生變動時的通知函數。例如,下面的代碼註冊了依賴屬性。

 

NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Student),  new PropertyMetadata("名稱", OnValueChanged));

 

     第四步:在前面的三步中,咱們完成了一個依賴屬性的註冊,那麼咱們怎樣才能對這個依賴屬性進行讀寫呢?答案就是提供一個依賴屬性的實例化包裝屬性,經過這個屬性來實現具體的讀寫操做。和CLR屬性不一樣,依賴屬性不是直接對私有變量的操縱,而是經過GetValue()和SetValue()方法來操做屬性值的,可使用標準的.NET屬性定義語法進行封裝,使依賴屬性能夠像標準屬性那樣來使用,代碼以下。

  public string Name

        {

            get { return (string)GetValue(NameProperty); }

            set { SetValue(NameProperty, value); }

        }

 

 

根據前面的四步操做,咱們就能夠寫出下面的代碼:

 

public class Student : DependencyObject 

    {

        //聲明一個靜態只讀的DependencyProperty字段

        public static readonly DependencyProperty NameProperty;

 

        static Student()

        {

            //註冊咱們定義的依賴屬性Name

            NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Student),

                new PropertyMetadata("名稱", OnValueChanged));

        }

 

        private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)

        {

            //當值改變時,咱們能夠在此作一些邏輯處理

        }

 

        //屬性包裝器,經過它來讀取和設置咱們剛纔註冊的依賴屬性

        public string Name

        {

            get { return (string)GetValue(NameProperty); }

            set { SetValue(NameProperty, value); }

        }

 

}

 

 

     總結:咱們通常.NET屬性是直接對類的一個私有屬性進行封裝,因此讀取值的時候,也就是直接讀取這個字段;而依賴屬性則是經過調用繼承自DependencyObject的GetValue()和SetValue來進行操做,它實際存儲在DependencyProperty的一個IDictionary的鍵-值配對字典中,因此一條記錄中的鍵(Key)就是該屬性的HashCode值,而值(Value)則是咱們註冊的DependencyProperty。

相關文章
相關標籤/搜索