相依性屬性中繼資料Dependency Property Metadata

Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF)屬性系統包含的元資料包告系統, 超出了透過反映或通用 common language runtime (CLR) 特性來報告屬性的內容。The Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) property system includes a metadata reporting system that goes beyond what can be reported about a property through reflection or general common language runtime (CLR) characteristics. 相依性屬性的中繼資料也可由定義相依性屬性的類別唯一指派、在相依性屬性新增至不同類別時變更,以及由從定義的基底類別繼承相依性屬性的所有衍生類別明確覆寫。Metadata for a dependency property can also be assigned uniquely by the class that defines a dependency property, can be changed when the dependency property is added to a different class, and can be specifically overridden by all derived classes that inherit the dependency property from the defining base class.

必要條件Prerequisites

本主題假設您已從 Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) 類別的現有相依性屬性消費者角度了解相依性屬性,並已閱讀相依性屬性概觀This topic assumes that you understand dependency properties from the perspective of a consumer of existing dependency properties on Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) classes, and have read the Dependency Properties Overview. 為了解本主題中的範例,您也應該了解 XAMLXAML 並知道如何撰寫 WPFWPF 應用程式。In order to follow the examples in this topic, you should also understand XAMLXAML and know how to write WPFWPF applications.

相依性屬性中繼資料的使用方式How Dependency Property Metadata is Used

相依性屬性中繼資料以物件的形式存在,可接受查詢來查看相依性屬性的特性。Dependency property metadata exists as an object that can be queried to examine the characteristics of a dependency property. 屬性系統也經常存取此中繼資料,因為它會處理任何指定的相依性屬性。This metadata is also accessed frequently by the property system as it processes any given dependency property. 相依性屬性的中繼資料物件可包含下列類型的資訊:The metadata object for a dependency property can contain the following types of information:

  • 相依性屬性的預設值 (如果無法由區域數值、樣式、繼承等判斷出相依性屬性的其他值)。如需預設值在屬性系統指派相依性屬性的值時所佔優先順序的完整說明,請參閱相依性屬性值優先順序Default value for the dependency property, if no other value can be determined for the dependency property by local value, style, inheritance, etc. For a thorough discussion of how default values participate in the precedence used by the property system when assigning values for dependency properties, see Dependency Property Value Precedence.

  • 影響各擁有者類型之強制型轉或變更通知行為的回呼實作參考。References to callback implementations that affect coercion or change-notification behaviors on a per-owner-type basis. 請注意,這些回呼通常是在非公用存取層級定義,因此一般無法從中繼資料取得實際參考,除非參考位於允許的存取範圍內。Note that these callbacks are often defined with a nonpublic access level, so obtaining the actual references from metadata is generally not possible unless the references are within your permitted access scope. 如需相依性屬性回呼的詳細資訊,請參閱相依性屬性回呼和驗證For more information on dependency property callbacks, see Dependency Property Callbacks and Validation.

  • 如果將考慮中的相依性屬性視為 WPF 架構層級屬性,中繼資料可能會包含 WPF 架構層級相依性屬性特性,以報告服務的資訊和狀態 (例如 WPF 架構層級配置引擎和屬性繼承邏輯)。If the dependency property in question is considered to be a WPF framework-level property, the metadata might contain WPF framework-level dependency property characteristics, which report information and state for services such as the WPF framework-level layout engine and property inheritance logic. 如需相依性屬性中繼資料在這方面的詳細資訊,請參閱架構屬性中繼資料For more information on this aspect of dependency property metadata, see Framework Property Metadata.

中繼資料 APIMetadata APIs

報告屬性系統所使用之大部分中繼資料資訊的型別是PropertyMetadata類別。The type that reports most of the metadata information used by the property system is the PropertyMetadata class. 當相依性屬性向屬性系統註冊時,會選擇性指定中繼資料執行個體,而且若有其他類型將自身作為擁有者新增或覆寫從基底類別相依性屬性定義繼承的中繼資料,則可再次指定中繼資料執行個體Metadata instances are optionally specified when dependency properties are registered with the property system, and can be specified again for additional types that either add themselves as owners or override metadata they inherit from the base class dependency property definition. (在屬性註冊未指定中繼資料的情況下, 會使用PropertyMetadata該類別的預設值建立預設值)。PropertyMetadata當您呼叫從DependencyObject實例上的相依性屬性取得中繼資料的各種多GetMetadata載時, 會傳回已註冊的中繼資料。(For cases where a property registration does not specify metadata, a default PropertyMetadata is created with default values for that class.)The registered metadata is returned as PropertyMetadata when you call the various GetMetadata overloads that get metadata from a dependency property on a DependencyObject instance.

然後PropertyMetadata , 類別會衍生自, 以針對架構分割 (例如 WPF 架構層級類別) 提供更具體的中繼資料。The PropertyMetadata class is then derived from to provide more specific metadata for architectural divisions such as the WPF framework-level classes. UIPropertyMetadata加入動畫報表, 並FrameworkPropertyMetadata提供上一節中所述的 WPF 架構層級屬性。UIPropertyMetadata adds animation reporting, and FrameworkPropertyMetadata provides the WPF framework-level properties mentioned in the previous section. 註冊相依性屬性時, 可以向這些PropertyMetadata衍生類別註冊。When dependency properties are registered, they can be registered with these PropertyMetadata derived classes. 當檢查中繼資料時, 基底PropertyMetadata類型可能會轉換成衍生類別, 讓您可以檢查更具體的屬性。When the metadata is examined, the base PropertyMetadata type can potentially be cast to the derived classes so that you can examine the more specific properties.

注意

在此檔中, 可以指定FrameworkPropertyMetadata的屬性特性有時稱為「旗標」。The property characteristics that can be specified in FrameworkPropertyMetadata are sometimes referred to in this documentation as "flags". 當您建立新的中繼資料實例以用於相依性屬性註冊或中繼資料覆寫時, 您可以使用FrameworkPropertyMetadataOptions旗標型列舉來指定這些值, 然後將列舉的可能串連值提供給FrameworkPropertyMetadata函數。When you create new metadata instances for use in dependency property registrations or metadata overrides, you specify these values using the flagwise enumeration FrameworkPropertyMetadataOptions and then you supply possibly concatenated values of the enumeration to the FrameworkPropertyMetadata constructor. 不過, 在結構化之後, 這些選項特性會FrameworkPropertyMetadata以一系列的布林值屬性 (而不是「結構化列舉值」) 的形式公開在中。However, once constructed, these option characteristics are exposed within a FrameworkPropertyMetadata as a series of Boolean properties rather than the constructing enumeration value. 布林值屬性可讓您查看每個條件,而不需要將遮罩套用到旗標型列舉值以取得所需的資訊。The Boolean properties enable you to check each conditional, rather than requiring you to apply a mask to a flagwise enumeration value to get the information you are interested in. 此函式會使用FrameworkPropertyMetadataOptions串連的, 以保持可合理的函式簽章長度, 而實際的結構化中繼資料會公開離散屬性, 讓查詢中繼資料更加直覺。The constructor uses the concatenated FrameworkPropertyMetadataOptions in order to keep the length of the constructor signature reasonable, whereas the actual constructed metadata exposes the discrete properties to make querying the metadata more intuitive.

何時覆寫中繼資料及衍生類別When to Override Metadata, When to Derive a Class

WPFWPF 屬性系統能夠變更相依性屬性的部分特性,而不需要重新實作整個屬性。The WPFWPF property system has established capabilities for changing some characteristics of dependency properties without requiring them to be entirely re-implemented. 這是由於相依性屬性位於特定類型上,因此可藉由為相依性屬性建構不同的屬性中繼資料執行個體來達成。This is accomplished by constructing a different instance of property metadata for the dependency property as it exists on a particular type. 請注意,大多數現有相依性屬性不是虛擬屬性,因此嚴格來說,要在繼承的類別上「重新實作」這些屬性,只能藉由鏡像處理現有成員來達成。Note that most existing dependency properties are not virtual properties, so strictly speaking "re-implementing" them on inherited classes could only be accomplished by shadowing the existing member.

如果您要嘗試為某個類型上的相依性屬性啟用的情節,無法藉由修改現有相依性屬性的特性來達成,則可能需要建立衍生類別,然後在該衍生類別上宣告自訂相依性屬性。If the scenario you are trying to enable for a dependency property on a type cannot be accomplished by modifying characteristics of existing dependency properties, it might then be necessary to create a derived class, and then to declare a custom dependency property on your derived class. 自訂相依性屬性的行為與 api 所WPFWPF定義的相依性屬性完全相同。A custom dependency property behaves identically to dependency properties defined by the WPFWPF APIs. 如需自訂相依性屬性的詳細資訊,請參閱自訂相依性屬性For more details about custom dependency properties, see Custom Dependency Properties.

您無法覆寫的相依性屬性有一個值得注意的特性,那就是它的實值型別。One notable characteristic of a dependency property that you cannot override is its value type. 如果您繼承的相依性屬性所具有的行為大致符合需求,但此相依性屬性需要不同的類型,就必須實作自訂相依性屬性,而且可能需要透過類型轉換或自訂類別上的其他實作連結屬性。If you are inheriting a dependency property that has the approximate behavior you require, but you require a different type for it, you will have to implement a custom dependency property and perhaps link the properties through type conversion or other implementation on your custom class. 此外, 您也無法取代現有ValidateValueCallback的, 因為此回呼存在於註冊欄位本身, 而不在其中繼資料內。Also, you cannot replace an existing ValidateValueCallback, because this callback exists in the registration field itself and not within its metadata.

變更現有中繼資料的情節Scenarios for Changing Existing Metadata

如果您使用現有相依性屬性的中繼資料,變更相依性屬性中繼資料的一個常見情節是變更預設值。If you are working with metadata of an existing dependency property, one common scenario for changing dependency property metadata is to change the default value. 變更或新增屬性系統回呼是更進階的情節。Changing or adding property system callbacks is a more advanced scenario. 如果您的衍生類別實作在相依性屬性之間有不同的相互關係,就可能會想要這麼做。You might want to do this if your implementation of a derived class has different interrelationships between dependency properties. 具有同時支援程式碼和宣告式使用方式之程式設計模型的條件之一,就是屬性必須能夠以任何順序設定。One of the conditionals of having a programming model that supports both code and declarative usage is that properties must enable being set in any order. 因此,任何相依性屬性都必須在沒有內容的情況下進行 Just-In-Time 設定,不能依賴建構函式中可能找到的設定順序來進行設定。Thus any dependent properties need to be set just-in-time without context and cannot rely on knowing a setting order such as might be found in a constructor. 如需屬性系統在這方面的詳細資訊,請參閱相依性屬性回呼和驗證For more information on this aspect of the property system, see Dependency Property Callbacks and Validation. 請注意,驗證回呼不是中繼資料的一部分,而是相依性屬性識別項的一部分。Note that validation callbacks are not part of the metadata; they are part of the dependency property identifier. 因此,您無法藉由覆寫中繼資料來變更驗證回呼。Therefore, validation callbacks cannot be changed by overriding the metadata.

在某些情況下,您可能也想變更現有相依性屬性上的 WPF 架構層級屬性中繼資料選項。In some cases you might also want to alter the WPF framework-level property metadata options on existing dependency properties. 這些選項會將 WPF 架構層級屬性的某些已知條件傳達給其他 WPF 架構層級處理序 (例如配置系統)。These options communicate certain known conditionals about WPF framework-level properties to other WPF framework-level processes such as the layout system. 設定選項通常只有在註冊新的相依性屬性時才會完成, 但是也可以在OverrideMetadataAddOwner呼叫中變更 WPF 架構層級的屬性中繼資料。Setting the options is generally done only when registering a new dependency property, but it is also possible to change the WPF framework-level property metadata as part of a OverrideMetadata or AddOwner call. 如需要使用的特定值和詳細資訊,請參閱架構屬性中繼資料For the specific values to use and more information, see Framework Property Metadata. 如需如何針對新註冊的相依性屬性設定這些選項的詳細資訊,請參閱自訂相依性屬性For more information that is pertinent to how these options should be set for a newly registered dependency property, see Custom Dependency Properties.

覆寫中繼資料Overriding Metadata

覆寫中繼資料的目的,主要是讓您有機會變更各種中繼資料衍生的行為,這些行為會套用到類型上的相依性屬性。The purpose of overriding metadata is primarily so that you have the opportunity to change the various metadata-derived behaviors that are applied to the dependency property as it exists on your type. 中繼資料一節會詳細說明原因。The reasons for this are explained in more detail in the Metadata section. 如需詳細資訊,包括一些程式碼範例,請參閱覆寫相依性屬性的中繼資料For more information including some code examples, see Override Metadata for a Dependency Property.

在註冊呼叫 (Register) 期間, 可以提供相依性屬性的屬性中繼資料。Property metadata can be supplied for a dependency property during the registration call (Register). 不過,在許多情況下,當您的類別繼承該相依性屬性時,您可能會想要為類別提供特定類型的中繼資料。However, in many cases, you might want to provide type-specific metadata for your class when it inherits that dependency property. 您可以藉由呼叫OverrideMetadata方法來執行這項操作。You can do this by calling the OverrideMetadata method. 如需WPFWPF api 的範例FrameworkElement , 類別是第一次註冊Focusable相依性屬性的型別。For an example from the WPFWPF APIs, the FrameworkElement class is the type that first registers the Focusable dependency property. 但是, false true Focusable類別會覆寫相依性屬性的中繼資料, 以提供它自己的初始預設值, 將它從變更為, 否則會重新使用原始的執行。 ControlBut the Control class overrides metadata for the dependency property to provide its own initial default value, changing it from false to true, and otherwise re-uses the original Focusable implementation.

當您覆寫中繼資料時,不同的中繼資料特性會被合併或取代。When you override metadata, the different metadata characteristics are either merged or replaced.

這個行為是由Merge所執行, 而且可以在衍生的中繼資料類別上覆寫。This behavior is implemented by Merge, and can be overridden on derived metadata classes.

覆寫附加屬性中繼資料Overriding Attached Property Metadata

WPFWPF 中,附加屬性會以相依性屬性的方式實作。In WPFWPF, attached properties are implemented as dependency properties. 這表示它們也有屬性中繼資料,可供個別類別覆寫。This means that they also have property metadata, which individual classes can override. 在中WPFWPF , 附加屬性的範圍考慮通常是任何DependencyObject可以設定的附加屬性。The scoping considerations for an attached property in WPFWPF are generally that any DependencyObject can have an attached property set on them. 因此, 任何DependencyObject衍生的類別都可以覆寫任何附加屬性的中繼資料, 因為它可能會在類別的實例上設定。Therefore, any DependencyObject derived class can override the metadata for any attached property, as it might be set on an instance of the class. 您可以覆寫預設值、回呼或 WPF 架構層級特性報告屬性。You can override default values, callbacks, or WPF framework-level characteristic-reporting properties. 如果在類別執行個體上設定附加屬性,則會套用這些覆寫屬性中繼資料特性。If the attached property is set on an instance of your class, those override property metadata characteristics apply. 例如,您可以覆寫預設值,只要沒有另外設定屬性,就會將覆寫值回報為類別執行個體上附加屬性的值。For instance, you can override the default value, such that your override value is reported as the value of the attached property on instances of your class, whenever the property is not otherwise set.

注意

Inherits屬性與附加屬性不相關。The Inherits property is not relevant for attached properties.

新增類別作為現有相依性屬性的擁有者Adding a Class as an Owner of an Existing Dependency Property

類別可以使用AddOwner方法, 將本身新增為已註冊之相依性屬性的擁有者。A class can add itself as an owner of a dependency property that has already been registered, by using the AddOwner method. 這可讓類別使用原本註冊給其他類型的相依性屬性。This enables the class to use a dependency property that was originally registered for a different type. 新增的類別通常不是原先註冊該相依性屬性作為擁有者之類型的衍生類別。The adding class is typically not a derived class of the type that first registered that dependency property as owner. 實際上,這可讓類別及其衍生類別「繼承」相依性屬性實作,而原始擁有者類別和新增的類別不需要在同一個真實類別階層中。Effectively, this allows your class and its derived classes to "inherit" a dependency property implementation without the original owner class and the adding class being in the same true class hierarchy. 此外,新增的類別 (及所有衍生類別) 接著可為原始相依性屬性提供特定類型的中繼資料。In addition, the adding class (and all derived classes as well) can then provide type-specific metadata for the original dependency property.

除了透過屬性系統公用程式方法自行新增作為擁有者,新增的類別也應在本身上宣告其他公用成員,讓相依性屬性完全融合在屬性系統中,並能公開給程式碼和標記。As well as adding itself as owner through the property system utility methods, the adding class should declare additional public members on itself in order to make the dependency property] a full participant in the property system with exposure to both code and markup. 新增現有相依性屬性的類別與定義新自訂相依性屬性的類別一樣,也必須公開該相依性屬性的物件模型。A class that adds an existing dependency property has the same responsibilities as far as exposing the object model for that dependency property as does a class that defines a new custom dependency property. 第一個要公開的成員是相依性屬性識別項欄位。The first such member to expose is a dependency property identifier field. 此欄位應該public static readonly是類型DependencyProperty的欄位, 它會指派給AddOwner呼叫的傳回值。This field should be a public static readonly field of type DependencyProperty, which is assigned to the return value of the AddOwner call. 要定義的第二個成員是 common language runtime (CLR) 「包裝函式」屬性。The second member to define is the common language runtime (CLR) "wrapper" property. 包裝函式可讓您更方便地在程式碼中操作相依性屬性 (您SetValue可以避免每次呼叫, 而且只能在包裝函式本身中呼叫一次)。The wrapper makes it much more convenient to manipulate your dependency property in code (you avoid calls to SetValue each time, and can make that call only once in the wrapper itself). 包裝函式的實作方式與註冊自訂相依性屬性時實作包裝函式的方式完全相同。The wrapper is implemented identically to how it would be implemented if you were registering a custom dependency property. 如需實作相依性屬性的詳細資訊,請參閱自訂相依性屬性新增相依性屬性的擁有者類型For more information about implementing a dependency property, see Custom Dependency Properties and Add an Owner Type for a Dependency Property.

AddOwner 和附加屬性AddOwner and Attached Properties

您可以針對AddOwner由 owner 類別定義為附加屬性的相依性屬性呼叫。You can call AddOwner for a dependency property that is defined as an attached property by the owner class. 一般這麼做的原因是要將先前的附加屬性公開為非附加相依性屬性。Generally the reason for doing this is to expose the previously attached property as a non-attached dependency property. 接著, 您會將AddOwner傳回值public static readonly公開為當做相依性屬性識別碼使用的欄位, 並定義適當的「包裝函式」屬性, 讓屬性出現在 members 資料表中, 並支援非附加屬性類別中的使用方式。You then will expose the AddOwner return value as a public static readonly field for use as the dependency property identifier, and will define appropriate "wrapper" properties so that the property appears in the members table and supports a non-attached property usage in your class.

另請參閱See also