共用方式為


屬性值繼承

屬性值繼承是 Windows Presentation Foundation (WPF) 屬性系統的功能。 屬性值繼承可讓元素樹狀結構中的子元素,在將它設定於最接近之父元素中的任一處時,可從父元素中取得特殊屬性的值,並繼承該值。 父元素可能也會透過屬性值繼承來取得它的值,因此,系統有可能會不停地遞迴到頁面根元素。 屬性值繼承不是預設的屬性系統行為;屬性必須使用特殊的中繼資料值來建立,才能讓該屬性起始子元素上的屬性值繼承。

屬性值繼承是內含項目繼承

「繼承」在此處做為一個詞彙,它不完全等同於類型內容中的繼承概念,且為一般物件導向程式設計,其中衍生的類別會繼承來自其基底類別的成員定義。 該繼承的意義也適用於 WPF︰定義於各種基底類別中的屬性 (Property) 均會在衍生的 XAML 類別用來做為元素時,公開為其屬性 (Attribute),並公開為程式碼的成員。 屬性值繼承特別是關於屬性值如何根據元素樹狀結構內的父/子關聯性,從某一個元素繼承至另一個元素。 當您在 XAML 標記中定義應用程式,於其他元素內巢串元素時,幾乎可以直接看見該元素樹狀結構。 物件的樹狀結構也可以透過程式設計方式,將物件新增至其他物件的指定集合來建立,而屬性值繼承會在執行階段,於完成的樹狀結構中以相同方式來運作。

屬性值繼承的實際應用程式

WPF API 包含數個已啟用屬性繼承的屬性。 一般而言,適用於這些屬性的案例是它們所包含的屬性適合在每個頁面上只設定該屬性一次,但該屬性也是其中一個基底元素類別的成員,因此,也會存在於大多數的子元素中。 例如,FlowDirection 屬性會控制應該在頁面上呈現哪一個方向流動的內容並加以排列。 一般而言,您會想要以一致性方式在所有子元素中處理文字流動的概念。 如果使用者或環境動作基於某些因素而在元素樹狀結構的某些層級中重設流動方向,則通常應該全部重設。 讓 FlowDirection 屬性進行繼承時,只需在元素樹狀結構的層級上設定或重設此值一次,該樹狀結構會包含在應用程式中呈現每個頁面的需求。 甚至連初始的預設值也將以這種方式繼承。 屬性值繼承模型仍可讓個別的元素在故意混合流動方向的罕見情況下重設值。

讓自訂屬性成為可繼承

藉由變更自訂屬性的中繼資料,您也可以讓自己的自訂屬性成為可繼承。 但請注意,將屬性指定為可繼承有一些效能考量。 假如該屬性沒有已建立的本機值,或是透過樣式、範本或資料繫結取得的值,可繼承的屬性就會為邏輯樹狀結構中的所有子元素提供其指派的屬性值。

若要讓參與值的屬性成為可繼承,請建立自訂的附加屬性,如註冊附加屬性中所述。 使用中繼資料 (FrameworkPropertyMetadata) 註冊屬性,並在該中繼資料內的選項設定中指定 「Inherits」 選項。 也請確定屬性具有已建立的預設值,因為該值現在將會繼承。 儘管您已將屬性註冊為附加,但您可能也想要針對擁有者類型上的 get/set 存取建立屬性「包裝函式」,就像您針對「非附加的」相依性屬性所做的一樣。 完成此動作之後,可繼承的屬性可以使用擁有者類型或衍生類型上的直接屬性包裝函式來設定,也可以使用任何 DependencyObject 上的附加屬性語法來設定。

附加屬性在概念上類似於全域屬性;您可以在任何 DependencyObject 上檢查此值,並取得有效的結果。 附加屬性的典型範例是在子元素上設定屬性值,而且如果有問題的屬性是一律會在樹狀結構的每個元素(DependencyObject) 上隱含顯示為附加屬性的附加屬性,則該案例會更有效率。

注意

雖然屬性值繼承似乎適用於非附加的相依性屬性,但在執行階段的樹狀結構中,透過特定元素界限的非附加屬性繼承行為是未定義的。 一律使用 RegisterAttached 來註冊您在中繼資料中指定 Inherits 的屬性。

跨樹狀結構界限繼承屬性值

屬性繼承的運作方式是周遊元素的樹狀結構。 此樹狀結構通常會與邏輯樹狀結構平行。 不過,每當您在定義元素樹狀結構的標記中加入 WPF 核心層級物件時 (例如 Brush),就表示您已建立不連續的邏輯樹狀結構。 真正的邏輯樹狀結構在概念上不會透過 Brush 來擴展,因為邏輯樹狀結構是一個 WPF 結構層級概念。 當您使用 LogicalTreeHelper 的方法時,會看到結果中反映出此概念。 不過,只要已將可繼承的屬性註冊為附加屬性且未遇到特意封鎖繼承的界限 (例如 Frame),屬性值繼承就可以在邏輯樹狀結構中填補此鴻溝,且仍可傳遞繼承的值。

另請參閱