Метаданные свойства зависимостиDependency Property Metadata

Система Windows Presentation Foundation (WPF)Windows Presentation Foundation (WPF) свойств включает в себя систему отчетности о метаданных, которая выходит за рамки того, что может быть сообщено о собственности через отражение или общие общие характеристики времени выполнения языка (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:

  • Значение по умолчанию для свойства зависимости, если никакое другое значение не может быть определено для свойства зависимости по локальной стоимости, стилю, наследованию и т.д. Для тщательного обсуждения того, как значения по умолчанию участвуют в приоритете, используемом Dependency Property Value Precedenceсистемой свойств при назначении значений для свойств зависимости, см.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.

Интерфейсы API метаданныхMetadata APIs

Тип, который сообщает большую часть информации о метаданных, используемой системой свойств, является классом. PropertyMetadataThe 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 при вызове различных GetMetadata перегрузок, которые получают метаданные из свойства зависимости на экземпляре. DependencyObject(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 характеристики опции подвергаются в пределах серии свойств Boolean, а не построения значения перечисления.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. Конструктор использует concatenated 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. Пользовательское свойство зависимости ведет себя одинаково свойствам WPFWPF зависимости, определенным AIS.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. Следовательно, все зависимые свойства необходимо настраивать в режиме JIT без контекста; при этом невозможно использовать какую-либо информацию о порядке настройки (которую можно найти, например, в конструкторе).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. Настройка опций обычно выполняется только при регистрации нового свойства зависимости, но также можно изменить метаданные OverrideMetadata AddOwner свойства уровня 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 FrameworkElement AI, класс — это тип, Focusable который сначала регистрирует свойство зависимости.For an example from the WPFWPF APIs, the FrameworkElement class is the type that first registers the Focusable dependency property. Но Control класс переопределяет метаданные для свойства зависимости, чтобы обеспечить false свое trueсобственное начальное значение Focusable по умолчанию, изменяя его с к , и в противном случае повторно использует исходную реализацию.But 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.

  • PropertyChangedCallbackсливается.PropertyChangedCallback is merged. Если вы добавите новый, PropertyChangedCallbackто обратный вызов хранится в метаданных.If you add a new PropertyChangedCallback, that callback is stored in the metadata. Если вы не PropertyChangedCallback указали в переопределении, значение повышается как ссылка от ближайшего PropertyChangedCallback предка, который указал его в метаданных.If you do not specify a PropertyChangedCallback in the override, the value of PropertyChangedCallback is promoted as a reference from the nearest ancestor that specified it in metadata.

  • Фактическое поведение системы свойств для PropertyChangedCallback того, чтобы реализации для всех владельцев метаданных в иерархии сохранялись и добавлялись в таблицу, при этом порядок выполнения системой свойств в том, что наиболее полученные группы вызовов вызываются в первую очередь.The actual property system behavior for PropertyChangedCallback is that implementations for all metadata owners in the hierarchy are retained and added to a table, with order of execution by the property system being that the most derived class's callbacks are invoked first.

  • DefaultValueзаменяется.DefaultValue is replaced. Если вы не DefaultValue укажете в переопределении, значение исходит от ближайшего DefaultValue предка, который указал его в метаданных.If you do not specify a DefaultValue in the override, the value of DefaultValue comes from the nearest ancestor that specified it in metadata.

  • CoerceValueCallbackреализации заменяются.CoerceValueCallback implementations are replaced. Если вы добавите новый, CoerceValueCallbackто обратный вызов хранится в метаданных.If you add a new CoerceValueCallback, that callback is stored in the metadata. Если вы не CoerceValueCallback указали в переопределении, значение повышается как ссылка от ближайшего CoerceValueCallback предка, который указал его в метаданных.If you do not specify a CoerceValueCallback in the override, the value of CoerceValueCallback is promoted as a reference from the nearest ancestor that specified it in metadata.

  • Поведение системы свойств заключается в том, что вызывается только CoerceValueCallback в непосредственных метаданных.The property system behavior is that only the CoerceValueCallback in the immediate metadata is invoked. Ссылки на CoerceValueCallback другие реализации в иерархии не сохраняются.No references to other CoerceValueCallback implementations in the hierarchy are retained.

Это поведение 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

Класс может добавить себя в качестве владельца свойства зависимости, которое уже зарегистрировано, с помощью метода. AddOwnerA 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. Вторым участником, определяющим, является свойство "обертки" общего языка (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 свойство зависимости, которое определяется как прилагаемое свойство классом владельца.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 поля для использования в качестве идентификатора свойств зависимости и определите соответствующие свойства "обертки", чтобы свойство отослало в таблице членов и поддерживало неприлагаемое использование свойств в вашем классе.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