2011/04/21

WPF中的Resource:DynamicResource與StaticResource的區別

來源:
http://translate.google.com.tw/translate?hl=zh-TW&sl=zh-CN&tl=zh-TW&u=http%3A%2F%2Fwww.cntxk.com%2FArchives%2Finfo1328.html&anno=2



什麼叫WPF的資源(Resource)?


資源是保存在可執行檔中的一種不可執行資料。 在WPF的資源中,幾乎可以包含圖像、字串等所有的任意CLR物件,只要物件有一個預設的構造函數和獨立的屬性。

也就是說,應用程式中非程式碼的內容,比如點陣圖、顏色、字型、動畫/影片檔以及字串常量值,可將它們從程式中獨立出來,單獨包裝成"資源(Resource)"。

靜態資源(Static Resource),動態資源(Dynamic Resources)。
這兩者的區別是:靜態資源在第一次編譯後即確定其對象或值,之後不能對其進行修改

動態資源則是在運行時決定,當運行過程中真正需要時,才到資源目標中查找其值。 因此,我們可以動態地修改它。 由於動態資源的運行時才能確定其值,因此效率比靜態資源要低。

資源的範圍(層級):

WPF提供一個封裝和存取資源(resource)的機制,我們可將資源建立在應用程式的不同範圍上。 WPF中,資源定義的位置決定了該資源的可用範圍。 資源可以定義在如下範圍中:

(1)物件級:此時,資源只能套用在這個Object物件,或套用至該物件的子物件。

(2)文件級:如果將資源定義在Window或Page層級的XAML檔中,那麼可以套用到這個檔中的所有物件。

(3)應用程式級:如果我們將資源定義在App.xaml 中,那麼,就可以將資源套用到應用程式內的任何地方。

(4)字典級:當我們把資源封裝成一個資源字典, 定義到一個ResourceDictionary的XAML檔時,就可以在另一個應用程式中重複使用。

每一個框架級元素(FrameworkElement 或者FrameworkContentElement)都有一個資源屬性。 每一個在資源字典中的資源都有一個唯一不重複的鍵值(key),在標籤中使用x:Key屬性來標識它。

 一般地,鍵值是一個字串,但你也可以用合適的擴展標籤來設置為其他物件類型。 非字元鍵值資源使用於特定的WPF區域,尤其是風格、元件資源,以及樣式資料等。

StaticResources的適用場合:

(1)在資源第一次引用之後無需再修改資源的值。

(2)資源引用不會基於運行時的行為進行重新計算,比如在重新載入Page/Window的時候。

(3)當需要設置的屬性不是DependencyObject或Freezable類型的時候,用StaticResource。

(4)當需要將資源編譯到dll中,並打包為程式的一部份,或者希望在各應用程式之間共用時,也使用StaticResource。

(5)當需要為一個自訂控制項創建一個Theme,並Theme中使用資源,就需要使用StaticResource。 因為StaticResource的資源查找行為時可預測的,並且本身包含在Theme中。 而對於DynamicResource,即使資源是定義在Theme中,也只能等到運行時確定,導致一些可能意料不到的情況發生。

(6)當需要使用資源設置大量的依賴屬性(Dependency Property)的時候。

由於依賴屬性具有屬性系統提供的值緩存機制,所以,如果能在程式裝載時設置依賴屬性的值,這樣,依賴屬性就不需要檢查自己的值並返回最後的有效值了。



Dynamic Resource一般使用在如下場合:

(1)資源的值依賴一些條件,而該條件直到運行時才能確定。

包括系統資源,或是使用者可設置的資源。 比如:可以創建引用系統屬性諸如SystemColors,SystemFonts來設置值,而這些屬性是動態的,它們的值又來自於運行環境和作業系統。

(2)為自訂控制項引用或創建Theme Style。

(3)希望在程式運行期間調整資源字典的內容時。

(4)希望資源可以向前引用時(如上面在Canvas中引用innerLgbResource一樣)

(5)資源檔很大,希望在運行時才載入。

(6)要創建的Style的值可能來自於其它值,而這些值又依賴於Theme或用戶的設置。

(7)當引用資源的元素的父元素有可能在運行期改變,這個時候也需要使用動態資源。 因為父元素的改變將導致資源查詢的範圍。

Dynamic resource的限制條件:屬性必須是依賴屬性,或是Freezable的。

資源的查詢方式

Static Resource的查詢

(1)查找使用該資源的元素的Resource字典;

(2)順著邏輯樹向上查找父元素的資源字典,直到根節點;

(3)查找Application資源;

(4)不支持向前引用,即:不能引用在引用點之後才定義的資源。


Dynamic Resource的查詢
(1)查找使用該資源的元素的Resource字典;

如果元素定義了一個Style 屬性,將查找Style中的資源字典;如果元素定義了一個Template屬性,將查找FrameworkTemplate中的資源字典。

(2)順邏輯樹向上查找父元素的資源字典,直到根節點;

(3)查找Application資源;

(4)查找當前啟動狀態下的Theme資源字