屬性值繼承

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

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

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

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

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

讓自訂屬性成為可繼承

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

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

附加屬性在概念上類似于全域屬性;您可以檢查任何 DependencyObject 的值,並取得有效的結果。 附加屬性的一般案例是在子項目上設定屬性值,如果有問題的 屬性是附加屬性,則這個案例會更有效率,該附加屬性一律會隱含地呈現為樹狀結構中每個元素 ( DependencyObject ) 上的附加屬性。

注意

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

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

屬性繼承的運作方式是周遊元素的樹狀結構。 此樹狀結構通常會與邏輯樹狀結構平行。 不過,當您在定義專案樹狀結構的標記中包含 WPF 核心層級物件時, Brush 您已建立不連續的邏輯樹狀結構。 真正的邏輯樹狀結構在概念上不會透過 Brush 延伸,因為邏輯樹狀結構是 WPF 架構層級的概念。 使用 的 方法 LogicalTreeHelper 時,您可以看到結果中反映此情況。 不過,屬性值繼承可以橋接邏輯樹狀結構中的這個間距,而且仍然可以透過 傳遞繼承的值,只要繼承屬性註冊為附加屬性,而且不會遇到任何刻意的繼承封鎖界限(例如 a Frame )。

另請參閱