Поделиться через


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

Система свойств Windows Presentation Foundation (WPF) включает систему отчетности метаданных, содержимое которой выходит за рамки того, что можно получить из отражения или общих характеристик common language runtime (CLR). Метаданные свойства зависимости также могут быть присвоены уникальным образом с помощью класса, в котором определено свойство зависимости, могут быть изменены, если свойство зависимости добавляется в другой класс, и могут быть переопределены специальным образом любым производным классом, наследующим свойство зависимости от определяющего базового класса.

В этом разделе содержатся следующие подразделы.

  • Предварительные требования
  • Принципы использования метаданных свойств зависимости
  • API-интерфейсы метаданных
  • Выбор между переопределением метаданных и созданием производного класса
  • Сценарии для изменения существующих метаданных
  • Связанные разделы

Предварительные требования

В этом разделе предполагается знакомство с принципом работы свойств зависимостей с точки зрения потребителя существующих свойств зависимостей классов Windows Presentation Foundation (WPF); кроме того, следует прочесть раздел Общие сведения о свойствах зависимости. Чтобы выполнить примеры в этом подразделе, следует также понимать принципы работы XAML и знать, как создаются приложения WPF.

Принципы использования метаданных свойств зависимости

Метаданные свойств зависимости существуют в виде объекта, к которому можно обращаться для проверки характеристик свойства зависимости. Также доступ к этим метаданным часто осуществляется с помощью системы свойств, которая обрабатывает любое заданное свойство зависимости. Объект метаданных свойства зависимости может содержать следующие типы данных:

  • Значение свойства зависимостей по умолчанию, если никакое другое значение не может быть определено для свойства зависимостей через локальное значение, стиль, наследование и т. д. Подробное описание того, как значения по умолчанию применяются системой свойств при присвоении значений свойствам зависимостей, см. в разделе Приоритет значения свойств зависимостей.

  • ссылки для реализации обратного вызова, влияющего на приведение типа данных или поведение при изменении уведомления на основе собственного типа данных. Обратите внимание, что такие обратные вызовы часто определяются с уровнем неоткрытого доступа, поэтому получение фактических ссылок из метаданных обычно невозможно, если ссылки не находятся в области разрешенного доступа. Дополнительные сведения об обратных вызовах свойства зависимости содержатся в разделе Проверка и обратные вызовы свойства зависимостей;

  • если свойство зависимости считается свойством уровня инфраструктуры WPF, метаданные могут содержать характеристики свойства зависимости уровня инфраструктуры WPF, которые содержат информацию и состояние для таких служб, как логика обработчика разметки уровня инфраструктуры WPF и свойств наследования. Дополнительные сведения об этом аспекте метаданных свойства зависимости см. в разделе Метаданные свойств среды.

API-интерфейсы метаданных

Типом, который сообщает большую часть сведений о метаданных, используемых системой свойств, является класс PropertyMetadata. Экземпляры метаданных указываются при необходимости, когда свойства зависимости регистрируются с помощью системы свойств, и могут быть определены снова для дополнительных типов, которые либо добавляют себя в качестве владельцев, либо переопределяют метаданные, которые они наследуют от определения свойства зависимости базового класса. (Для случаев, когда при регистрации свойства не указаны метаданные, создается класс PropertyMetadata по умолчанию со стандартными для этого класса значениями.) Зарегистрированные метаданные возвращаются в виде PropertyMetadata при вызове перегруженных методов GetMetadata, которые получают метаданные из свойства зависимости экземпляра класса DependencyObject.

Затем вызывается производный класс PropertyMetadata, который предоставляет дополнительные метаданные для архитектурных делений, например на классы уровня платформы WPF. UIPropertyMetadata добавляет отчетность анимации, а FrameworkPropertyMetadata предоставляет свойства уровня платформы WPF, упомянутые в предыдущем разделе. При регистрации свойства зависимости могут быть зарегистрированы с производными классами PropertyMetadata. При проверке метаданных базовый тип PropertyMetadata может быть потенциально приведен к производным классам, что дает возможность получить доступ к дополнительным свойствам.

ПримечаниеПримечание

В данной документации иногда приводятся ссылки на характеристики свойства, которые могут быть определены в классе FrameworkPropertyMetadata («флаги»).При создании новых экземпляров метаданных для использования при регистрации свойства зависимости или переопределении метаданных можно задать эти значения с помощью флагового перечисления FrameworkPropertyMetadataOptions, а затем указать возможные сцепления значений перечисления в конструкторе FrameworkPropertyMetadata.Однако после создания эти характеристики параметра представляются в классе FrameworkPropertyMetadata как ряд логических свойств, а не как созданные значения перечисления.Логические свойства позволяют проверить каждое условие без необходимости применять маску для значения флагового перечисления, чтобы получить требуемую информацию.Чтобы сохранить длину сигнатуры конструктора приемлемой, конструктор использует объединенные параметры FrameworkPropertyMetadataOptions, тогда как фактически построенные метаданные предоставляют дискретные свойства, чтобы сделать запрос метаданных более наглядным.

Выбор между переопределением метаданных и созданием производного класса

Система свойств WPF имеет установленные возможности для изменения некоторых характеристик свойств зависимости, не требуя их полного пересоздания. Это достигается путем создания другого экземпляра метаданных свойства для свойства зависимости, так как оно существует в качестве определенного типа. Следует отметить, что большинство существующих свойств зависимостей не являются виртуальными свойствами, поэтому, строго говоря, их повторная реализация в наследуемых классах может быть произведена только путем переобъявления существующего члена.

Если требуемый скрипт для свойства зависимости в типе не может быть выполнен путем изменения характеристик существующих свойств зависимости, возможно, потребуется создать производный класс и затем объявить настраиваемое свойство зависимости для производного класса. Поведение настраиваемого свойства зависимости аналогично свойствам зависимости, определенным в WPF APIs. Дополнительные сведения о настраиваемых свойствах зависимости см. в разделе Пользовательские свойства зависимостей.

Единственной важной характеристикой свойства зависимости, которая не может быть переопределена, является тип значения. Если наследуемое свойство зависимости ведет себя приблизительно так, как ожидается, но необходим другой его тип, потребуется реализовать настраиваемое свойство зависимости и, возможно, связать свойства с помощью преобразования типов или других реализаций данного настраиваемого класса. Кроме того, невозможно заменить существующий обратный вызов ValidateValueCallback, так как он находится в поле регистрации и не входит в метаданные.

Сценарии для изменения существующих метаданных

При работе с метаданными существующего свойства зависимости одним из распространенных скриптов для изменения метаданных свойства зависимости является изменение значения по умолчанию. Изменение или добавление обратных вызовов системы свойств является более сложным способом. Это может потребоваться, если данная реализация производного класса имеет различные взаимосвязи между свойствами зависимости. Одним из условий модели программирования, поддерживающей как код, так и декларативное использование, является то, что свойства должны устанавливаться в любом порядке. Таким образом, значения всех зависимых свойств необходимо установить своевременно без контекста; нельзя полагаться на знание порядка присвоения значений, который может быть доступен в конструкторе. Дополнительные сведения об этом аспекте системы свойств содержатся в разделе Проверка и обратные вызовы свойства зависимостей. Следует отметить, что обратные вызовы проверки данных не являются частью метаданных; они являются частью идентификатора свойства зависимости. Таким образом, обратные вызовы проверки не могут быть изменены путем переопределения метаданных.

В некоторых случаях может также потребоваться изменение параметров метаданных свойства уровня инфраструктуры WPF в существующих свойствах зависимости. Эти параметры связывают некоторые известные условия свойств уровня инфраструктуры WPF и другие процессы уровня инфраструктуры WPF, такие как система разметки. Настройка параметров обычно выполняется только при регистрации нового свойства зависимости, но изменить метаданные свойства уровня инфраструктуры WPF можно путем вызова методов OverrideMetadata или AddOwner. Конкретные значения для использования и дополнительные сведения содержатся в разделе Метаданные свойств среды. Дополнительные сведения о том, как должны быть заданы эти параметры для вновь зарегистрированных свойств зависимости, см. в разделе Пользовательские свойства зависимостей.

Переопределение метаданных

Основной целью переопределения метаданных является то, что у разработчика появляется возможность изменить некоторые характеристики производных метаданных, которые применяются к свойству зависимости, как оно существует в данном типе. Причины этого более подробно описаны в разделе Метаданные. Дополнительные сведения, включая примеры кода, содержатся в разделе Практическое руководство. Переопределение метаданных для свойств зависимости.

Метаданные свойства могут быть предоставлены свойству зависимости во время регистрационного вызова (Register). Однако в большинстве случаев может потребоваться предоставление метаданных определенного типа для класса, когда он наследует свойство зависимости. Это можно сделать, вызвав метод OverrideMetadata. Рассмотрим пример из APIs WPF. Класс FrameworkElement является типом, который первоначально регистрирует свойство зависимостей Focusable. Но класс Control переопределяет метаданные свойства зависимостей, чтобы обеспечить его собственным исходным значением по умолчанию, изменяя его с false на true, в противном случае повторно использует исходную реализацию Focusable.

При переопределении метаданных различные характеристики метаданных либо объединяются, либо замещаются.

  • Объект PropertyChangedCallback объединяется. Если добавить новый обратный вызов PropertyChangedCallback, он сохранится в метаданных. Если в переопределении не указан обратный вызов PropertyChangedCallback, значение PropertyChangedCallback переходит в качестве ссылки из ближайшего родительского объекта, указанного в метаданных.

  • Фактическое поведение системы свойств PropertyChangedCallback заключается в том, что реализации для всех владельцев метаданных в иерархии сохраняются и добавляются в таблицу в порядке выполнения системой свойств (сначала вызывается большинство обратных вызовов производного класса).

  • Объект DefaultValue заменяется. Если в переопределении не указан обратный вызов DefaultValue, значение DefaultValue переходит из ближайшего родительского объекта, указанного в метаданных.

  • Реализации CoerceValueCallback заменяются. Если добавить новый обратный вызов CoerceValueCallback, он сохранится в метаданных. Если в переопределении не указан обратный вызов CoerceValueCallback, значение CoerceValueCallback переходит в качестве ссылки из ближайшего родительского объекта, указанного в метаданных.

  • Поведение системы свойств состоит в том, что только CoerceValueCallback вызывается непосредственно из метаданных. Ссылки на другие реализации CoerceValueCallback в иерархии не сохраняются.

Такое поведение реализовано в классе Merge и может быть переопределено в производных классах метаданных.

Переопределение вложенного свойства метаданных

В WPF вложенные свойства реализуются как свойства зависимости. Это означает, что они также имеют метаданные свойства, которые отдельные классы могут переопределить. Проблемы видимости для вложенного свойства в WPF сводятся к тому, что любой объект DependencyObject может иметь свой набор присоединенных свойств. Таким образом, любой производный класс DependencyObject может переопределить метаданные любого вложенного свойства так же, как они могут быть заданы в экземпляре класса. Переопределению подлежат значения по умолчанию, обратные вызовы или свойства сведений о характеристиках уровня инфраструктуры WPF. Если вложенное свойство установлено для экземпляра класса, применяются такие переопределенные характеристики метаданных свойства. Например, можно переопределить значение по умолчанию таким образом, что всякий раз переопределенное значение будет отображаться как значение вложенного свойства экземпляра класса, если свойство не задано иным образом.

ПримечаниеПримечание

Свойство Inherits не относится к вложенным свойствам.

Добавление класса в качестве владельца существующего свойства зависимости

Используя метод AddOwner, класс может сделать себя владельцем уже зарегистрированного свойства зависимости. Это позволяет классу использовать свойство зависимости, первоначально зарегистрированное для другого типа. Добавленный класс обычно не является производным классом того типа, который первоначально зарегистрировал свойство зависимости в качестве владельца. Фактически, это позволяет классу и его производным классам «наследовать» реализацию свойства зависимости, не используя исходный класс-владелец и добавленный класс из той же действительной иерархии классов. Кроме того, добавляющий класс (а также все производные классы) может предоставлять метаданные, определяемые типом, для исходного свойства зависимости.

Также как и добавление себя в качестве владельца с помощью вспомогательных методов системы свойств, добавляющий класс должен объявить дополнительные открытые члены, чтобы сделать свойство зависимости полноценным участником системы свойств с возможностью доступа к коду и разметке. Класс, который добавляет существующее свойство зависимости, обладает теми же возможностями при предоставлении доступа к объектной модели для этого свойства зависимости, что и класс, который определяет новое пользовательское свойство зависимости. Поле идентификатора свойства зависимости является первым таким членом. Это поле должно быть полем public static readonly типа DependencyProperty, которому присваивается возвращаемое значение вызова AddOwner. Вторым элементом определения является свойство «оболочки» common language runtime (CLR). Оболочка делает управление свойством зависимости в коде гораздо более удобным (можно избежать неоднократных вызовов SetValue: этот вызов совершается в оболочке только один раз). Программа-оболочка реализуется так же, как и при регистрации пользовательского свойства зависимостей. Дополнительные сведения о реализации свойства зависимостей см. в разделах Пользовательские свойства зависимостей и Практическое руководство. Добавление типа владельца для свойства зависимости.

Метод AddOwner и вложенные свойства

Можно вызвать метод AddOwner для свойства зависимости, которое определено классом-владельцем как вложенное свойство. Обычно, основанием для этого является представление ранее вложенного свойства в качестве неприсоединенного свойства зависимости. Затем будет получено возвращаемое значение метода AddOwner в виде поля public static readonly для использования в качестве идентификатора свойства зависимости и будут определены соответствующие свойства «оболочки» так, что свойство появится в таблице элементов и будет поддерживать использование невложенного свойства в классе.

См. также

Ссылки

PropertyMetadata

DependencyObject

DependencyProperty

GetMetadata

Основные понятия

Общие сведения о свойствах зависимости

Метаданные свойств среды