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

2022-02-09 08:09:21 字數 3426 閱讀 7102

一、依賴屬性基本介紹

本篇開始學習wpf的另乙個重要內容依賴屬性。

大家都知道wpf帶來了很多新的特性,其中乙個就是引入了一種新的屬性機制——依賴屬性。依賴屬性出現的目的是用來實現wpf中的樣式、自動繫結及實現動畫等特性。依賴屬性的出現是wpf這種特殊的呈現原理派生出來的,與.net普通屬性不同的是,依賴屬性的值是依靠多個提供程式來判斷的,並且其具有內建的傳遞變更通知的能力。

依賴屬性基本應用在了wpf的所有需要設定屬性的元素。依賴屬性根據多個提供物件來決定它的值 (可以是動畫、父類元素、繫結、樣式和模板等),同時這個值也能及時響應變化。

依賴屬性就是可以自己沒有值,並能夠通過binding從資料來源獲 取值(依賴在別人身上)的屬性。擁有依賴屬性的物件被稱為「依賴物件」。依賴項屬性的重點在於「依賴」二字,既然是依賴了,也就是說:依賴項屬性的值的改變過程一定與其它對相關,不a依賴b就b依賴a,或者相互依賴。

說白了,所謂依賴,主要應用在以下地方:

1、雙向繫結。有了這個,依賴項屬性不用寫額的**,也不用實現什麼介面,它本身就俱備雙向繫結的特性,比如,我把員工物件的姓名繫結到搖文字框,一旦繫結,只要文字框中的值發生改變,依賴項屬性員工姓名也會跟著變化,反之亦然;

2、觸發器。這個東西在wpf中很重要,比如,乙個按鈕背景是紅色,我想讓它在滑鼠停留在它上面是背景變成綠色,而滑鼠一旦移開,按鈕恢復紅色。

如果在傳統的windows程式設計中,你一定會想辦法弄一些事件,或者委託來處理,還要寫一堆**。告訴你,有了依賴項屬性,你將一行**都不用寫,所有的處理均由wpf屬性系統自動處理。而觸發器只是臨時改變屬性的值,當觸完成時,屬性值自動被「還原」。

3、附加屬性。附加屬性也是依賴項屬性,它可以把a型別的的某些屬性推遲到執行時根據b型別的具體情況來進行設定,而且可以同時被多個型別物件同時維護同乙個屬性值,但每個例項的屬性值是獨立的。

4、a屬性改變時,也同時改變其它屬性的值,如toglebutton按下的同時,彈出下拉框。

與傳統的clr屬性和物件導向相比依賴屬性有很多新穎之處,其中包括:

1、新功能的引入:加入了屬性變化通知,限制、驗證等等功能,這樣就可以使我們更方便的實現我們的應用,同時也使**量大大減少了,許多之前不可能的功能都可以輕鬆的實現了。

2、 節約記憶體:在winform等專案開發中,你會發現ui控制項的屬性通常都是賦予的初始值,為每乙個屬性儲存乙個欄位將是對記憶體的巨大浪費。wpf依賴屬性 允許物件在被建立的時候並不包含用於儲存資料的空間(即字段所占用的空間)、只保留在需要用到資料的時候能夠獲得預設值。借用其它物件的資料或者實

時分配空間的能力----這種物件稱為依賴物件而他這種實時獲取資料的能力則依靠依賴屬性來實現。在wpf開發中,必須使用依賴物件作為依賴屬性的宿主,

使二者結合起來,才能形成完整的binding目標被資料所驅動。。

3、支援多個提供物件:我們可以通過多種方式來設定依賴屬性的值。同時其內部可以儲存多個值,配合expression、style、animation等可以給我們帶來很強的開發體驗。

在.net當中,對於屬性是大家應該很熟悉,封裝類的字段,表示類的狀態,編譯後被轉化為對應的get和set方法。屬性可以被類或結構等使用。 乙個簡單的屬性如下,也是我們常用的寫法:

public class student

set

}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

set

}

根據前面的四步操作,我們就可以寫出下面的**:

public class student : dependencyobject 

private static void onvaluechanged(dependencyobject o, dependencypropertychangedeventargs e)

//屬性包裝器,通過它來讀取和設定我們剛才註冊的依賴屬性

public string name

set

}}

總結:我們一般.net屬性是直接對類的乙個私有屬性進行封裝,所以讀取值的時候,也就是直接讀取這個字段;而依賴屬性則是通過呼叫繼承自dependencyobject的getvalue()和setvalue來進行操作,它實際儲存在dependencyproperty的乙個idictionary的鍵-值配對字典中,所以一條記錄中的鍵(key)就是該屬性的hashcode值,而值(value)則是我們註冊的dependencyproperty。

WPF入門教程系列(4)

mvvmlight安裝之後,我們可以看到簡易的框架布局,生成了乙個viewmodel資料夾,viewmodel層的內容都放在這邊,除了main物件的viewmodel之外,還包含乙個viewmodellocator檔案,用來注入當前的viewmodel全域性例項。一 先來說說分層結構 如圖 1 vi...

WPF入門教程系列(5)

很簡單,僅僅是包含乙個實體物件,這邊注意的的是那他繼承了乙個父類 observableobject,這個父類的作用就是保證能夠檢測屬性是否被改變。其實在繼承的過程中,可能會遇到乙個問題 observableobject無法被繼承,解決方案是加乙個using galasoft.mvvmlight 命名...

WPF入門教程系列一

一 前言 公司專案基於wpf開發,最近專案上線有點空閒時間寫一篇基於wpf的基礎教材,wpf也是近期才接觸,學習wpf也是在網上查資料與微軟的msdn進行學習,寫本部落格的目為了溫故而知新把學習過程記錄下來,以備後查。學習wpf的基礎知識 1 wpf是微軟提供的一種用來開發 桌面應用 的技術 框架 ...