共用方式為


相依性屬性元資料 (WPF .NET)

Windows Presentation Foundation (WPF) 屬性系統包含相依性屬性元數據報告系統。 透過元數據報告系統取得的信息超過透過反映或一般 Common Language Runtime (CLR) 特性提供的資訊。 當您註冊相依性屬性時,您可以選擇建立和指派元數據給它。 如果您衍生自定義相依性屬性的類別,您可以覆寫繼承之相依性屬性的元數據。 而且,如果您將類別新增為相依性屬性的擁有者,您可以覆寫繼承之相依性屬性的元數據。

必要條件

本文假設您具備相依性屬性的基本知識,而且您已閱讀 相依性屬性概觀。 若要遵循本文中的範例,如果您熟悉可延伸的應用程式標記語言(XAML),並知道如何撰寫 WPF 應用程式,它很有説明。

如何使用元數據

您可以查詢相依性屬性元數據,以檢查相依性屬性的特性。 當屬性系統處理相依性屬性時,它會存取其元數據。 相依性屬性的元資料物件包含下列類型的資訊:

  • 相依性屬性的預設值,在未套用其他值時由屬性系統設定,例如本機、樣式或繼承值。 如需相依性屬性值運行時間指派期間值優先順序的詳細資訊,請參閱 相依性屬性值優先順序

  • 強制值回呼和屬性在擁有者類型上變更回呼的參考。 您只能取得具有 public 存取修飾詞或在您允許存取範圍內之回呼的參考。 如需相依性屬性回呼的詳細資訊,請參閱 相依性屬性回呼和驗證

  • WPF 架構層級相依性屬性特性(如果相依性屬性是 WPF 架構屬性)。 WPF 進程,例如架構配置引擎和屬性繼承邏輯,查詢 WPF 架構層級元數據。 如需詳細資訊,請參閱 Framework 屬性元數據

中繼資料 API

類別 PropertyMetadata 會儲存屬性系統所使用的大部分元數據。 元數據實例的建立和指派方式如下:

  • 向屬性系統註冊相依性屬性的類型。

  • 繼承自定義相依性屬性之類別的類型。

  • 將自己新增為相依性屬性擁有者的類型。

如果類型註冊相依性屬性而不指定元數據,則屬性系統會將 PropertyMetadata 具有該類型之預設值的物件指派給相依性屬性。

若要擷取相依性屬性的DependencyProperty元數據,請在標識符上呼叫其中GetMetadata一個多載。 元數據會以 PropertyMetadata 物件的形式傳回。

衍生自 PropertyMetadata的更特定元數據類別會針對不同的架構區域而存在。 例如, UIPropertyMetadata 支持動畫報告,並支援 FrameworkPropertyMetadata WPF 架構屬性。 相依性屬性也可以向 PropertyMetadata 衍生類別註冊。 雖然 GetMetadata 會傳 PropertyMetadata 回 物件,但當適用時,您可以轉換成衍生類型來檢查類型特定的屬性。

FrameworkPropertyMetadata 公開的屬性特性有時稱為 旗標。 當您建立 FrameworkPropertyMetadata 實例時,您可以選擇將列舉類型的 FrameworkPropertyMetadataOptions 實例傳遞至 FrameworkPropertyMetadata 建構函式。 FrameworkPropertyMetadataOptions 可讓您以位組合指定元數據旗標。 會 FrameworkPropertyMetadata 使用 FrameworkPropertyMetadataOptions 保持其建構函式簽章的長度合理。 在相依性屬性註冊上,您設定的FrameworkPropertyMetadataOptions元數據旗標會公開為Boolean屬性,FrameworkPropertyMetadata而不是旗標的位元組合,讓查詢元數據特性更直覺。

覆寫或建立新的元數據?

當您繼承相依性屬性時,您可以選擇覆寫相依性屬性的元數據來變更相依性屬性的特性。 不過,您不一定能夠透過覆寫元數據來完成相依性屬性案例,有時必須使用新的元數據在類別中定義自定義相依性屬性。 自定義相依性屬性的功能與 WPF 類型所定義的相依性屬性相同。 如需詳細資訊,請參閱 自定義相依性屬性

您無法覆寫之相依性屬性的其中一個特性是其實值類型。 如果繼承的相依性屬性具有您需要的近似行為,但您的案例需要不同的實值類型,請考慮實作自定義相依性屬性。 您可以透過型別轉換或其他衍生類別中的實作來連結屬性值。

覆寫元數據的案例

覆寫現有相依性屬性元數據的範例案例如下:

  • 變更預設值,這是常見的案例。

  • 變更或新增屬性變更回呼,如果繼承的相依性屬性與其他相依性屬性的互動方式與其基底實作不同,則可能是必要的。 支援程式代碼和標記的程序設計模型其中一個特性,就是屬性值可能依任何順序設定。 這個因素可能會影響您實作屬性變更回呼的方式。 如需詳細資訊,請參閱 相依性屬性回呼和驗證

  • 變更 WPF 架構屬性元數據 選項。 一般而言,元數據選項會在新相依性屬性的註冊期間設定,但您可以在 或 AddOwner 呼叫中OverrideMetadata重新指定它們。 如需覆寫架構屬性元數據的詳細資訊,請參閱 指定 FrameworkPropertyMetadata。 如需如何在註冊相依性屬性時設定架構屬性元數據選項,請參閱 自定義相依性屬性

注意

由於驗證回呼不是元數據的一部分,因此無法藉由覆寫元數據來變更。 如需詳細資訊,請參閱 驗證值回呼。

覆寫元數據

實作新的相依性屬性時,您可以使用 方法的多 Register 載來設定其元數據。 如果您的類別繼承相依性屬性,您可以使用 方法覆寫繼承的元數據值 OverrideMetadata 。 例如,您可以使用 OverrideMetadata 來設定類型特定的值。 如需詳細資訊和程式代碼範例,請參閱 覆寫相依性屬性的元數據。

WPF 相依性屬性的範例是 Focusable。 類別 FrameworkElementFocusable註冊 。 類別 Control 衍生自 FrameworkElement,繼承 Focusable 相依性屬性,並覆寫繼承的屬性元數據。 覆寫會將預設屬性值從 false 變更為 true,但會保留其他繼承的元數據值。

由於大部分現有的相依性屬性不是虛擬屬性,因此其繼承的實作會遮蔽現有的成員。 當您覆寫元資料特性時,新的元數據值會取代原始值或合併:

  • DefaultValue針對,新的值會取代現有的預設值。 如果您未在覆寫元數據中指定 DefaultValue ,則值會來自元數據中指定的最接近上階 DefaultValue

  • PropertyChangedCallback針對,預設合併邏輯會將所有PropertyChangedCallback值儲存在數據表中,而且所有值都會在屬性變更時叫用。 回呼順序取決於類別深度,其中階層中基類所註冊的回呼會先執行。

  • CoerceValueCallback針對,新的值將會取代現有的CoerceValueCallback值。 如果您未在覆寫元數據中指定 CoerceValueCallback ,則值會來自元數據中指定的最接近上階 CoerceValueCallback

注意

默認合併邏輯是由 Merge 方法實作。 您可以在繼承相依性屬性的衍生類別中指定自定義合併邏輯,方法是在該類別中覆寫 Merge

將類別新增為擁有者

若要「繼承」在不同類別階層中註冊的相依性屬性,請使用 AddOwner 方法。 當新增類別不是衍生自註冊相依性屬性的類型時,通常會使用這個方法。 在呼叫中 AddOwner ,新增類別可以建立並指派繼承相依性屬性的類型特定元數據。 若要成為屬性系統的完整參與者,透過程式代碼和標記,新增類別應該實作這些公用成員:

  • 相依性屬性標識碼欄位。 相依性屬性標識碼的值是呼叫的 AddOwner 傳回值。 此欄位應該是 public static readonly 類型的 DependencyProperty欄位。

  • 實作 和 set 存取子的 get CLR 包裝函式。 藉由使用屬性包裝函式,相依性屬性的取用者可以取得或設定相依性屬性值,就像任何其他 CLR 屬性一樣。 getset 存取子會透過 DependencyObject.GetValueDependencyObject.SetValue 呼叫與基礎屬性系統互動,並傳入相依性屬性標識碼做為參數。 以註冊自定義相依性屬性時的相同方式實作包裝函式。 如需詳細資訊,請參閱 自定義相依性屬性

呼叫 AddOwner 的類別,對於公開繼承之相依性屬性的物件模型,具有相同的需求,做為定義新自定義相依性屬性的類別。 如需詳細資訊,請參閱 新增相依性屬性的擁有者類型。

附加屬性元數據

在 WPF 中,WPF 類型上大部分與 UI 相關的附加屬性都會實作為相依性屬性。 實作為相依性屬性的附加屬性支援相依性屬性概念,例如衍生類別可以覆寫的元數據。 附加屬性的元數據通常與相依性屬性不同。 您可以在覆寫類別的實體上覆寫繼承附加屬性的預設值、屬性變更回呼和 WPF 架構屬性。 如需詳細資訊,請參閱 附加屬性元數據

注意

一律使用 RegisterAttached 來註冊您在 Inherits 元數據中指定的屬性。 雖然屬性值繼承可能適用於非附加的相依性屬性,但未定義運行時間樹狀結構中特定物件物件分割之非附加屬性的值繼承行為。 屬性 Inherits 與未附加的屬性無關。 如需詳細資訊,請參閱 RegisterAttached(String, Type, Type, PropertyMetadata)的和備註一節 Inherits

將類別新增為附加屬性的擁有者

若要從另一個類別繼承附加屬性,但將其公開為類別上的非附加相依性屬性:

  • 呼叫 AddOwner 以將類別新增為附加相依性屬性的擁有者。

  • 將呼叫的 AddOwner 傳回值指派給 public static readonly 字段,以做為相依性屬性標識符。

  • 定義 CLR 包裝函式,此包裝函式會將 屬性新增為類別成員,並支援非附加的屬性使用方式。

另請參閱