Метаданные свойства зависимости
Система свойств Windows Presentation Foundation (WPF) включает систему отчетности по метаданным, которая выходит за пределы стандартной отчетности о свойстве, отражая общие характеристики CLR. Метаданные для свойства зависимости также можно уникально назначить для отдельного класса, который определяет свойство зависимости, можно изменить, когда свойство зависимости добавляется в другой класс, и можно переопределить, в частности, всеми производными классами, наследующими свойство зависимости от определяющего базового класса.
Предварительные требования
Предполагается, что вы имеете представление о свойствах зависимостей с точки зрения потребителя существующих свойств зависимостей в классах Windows Presentation Foundation (WPF) и ознакомились с разделом Общие сведения о свойствах зависимостей. Чтобы выполнить примеры в этом разделе, следует также иметь представление о XAML и написании приложений WPF.
Как используются метаданные свойства зависимости
Метаданные свойств зависимости существуют в виде объекта, которому можно направлять запросы, чтобы проанализировать свойство зависимости. Система свойств также часто осуществляет доступ к этим метаданным, обрабатывая то или иное свойство зависимости. Объект метаданных для свойства зависимости может содержать следующие сведения.
Значение по умолчанию для свойства зависимости, если никакое другое значение для свойства зависимости не может быть определено локальным значением, стилем, наследованием и т. д. Подробное описание того, как значения по умолчанию применяются системой свойств при определении приоритета присвоения значений для свойств зависимостей, см. в разделе Приоритет значения свойства зависимости.
Ссылки на реализации обратных вызовов, которые влияют на поведение приведения или уведомления об изменении для каждого типа владельца. Обратите внимание, что эти обратные вызовы часто определяются закрытым уровнем доступа, поэтому получить реальные ссылки из метаданных, как правило, невозможно, если только эти ссылки не находятся внутри области, к которой у вас имеется доступ. Дополнительные сведения об обратных вызовах свойств зависимости см. в разделе Обратные вызовы свойств зависимости и проверка.
Если рассматриваемое свойство зависимости является свойством уровня среды WPF, метаданные могут содержать характеристики свойства зависимости уровня среды WPF, сообщающие информацию о службах и их состоянии, например модуле макетов уровня среды WPF и логику наследования свойств. Дополнительные сведения об этом аспекте метаданных свойства зависимости см. в разделе Метаданные свойств среды.
Интерфейсы API метаданных
Тип, сообщаемый большая часть сведений метаданных, используемых системой свойств является PropertyMetadata класса. Экземпляры метаданных указываются при необходимости, когда свойства зависимости регистрируются в системе свойств; их можно повторно указать для дополнительных типов, добавляющихся в качестве владельцев или переопределяющих метаданные, которые они наследуют от определения свойства зависимости базового класса. (Для случаев, когда Регистрация свойства не указаны метаданные, по умолчанию PropertyMetadata создается со значениями по умолчанию для этого класса.) Зарегистрированные метаданные возвращаются в виде PropertyMetadata при вызове различных GetMetadata перегрузки, которые получают метаданные от свойства зависимости на DependencyObject экземпляра.
PropertyMetadata Класс является производным от затем предоставить более конкретные метаданные для подразделений архитектуры, такие как классы уровня среды WPF. UIPropertyMetadata Добавляет отчетность по анимации, и FrameworkPropertyMetadata предоставляет свойства уровня среды WPF, упомянутые в предыдущем разделе. При регистрации свойства зависимостей, их можно зарегистрировать с помощью этих PropertyMetadata производных классов. При проверке метаданных, базовый PropertyMetadata типа можно привести к производным классам, потенциально, чтобы можно было проверить более конкретные свойства.
Note
Характеристики свойства, которые могут быть указаны в FrameworkPropertyMetadata , иногда называют в этой документации «флагами». При создании новых экземпляров метаданных для использования в зависимости регистрации свойства или переопределяет метаданные, необходимо указать эти значения, с использованием флагового перечисления FrameworkPropertyMetadataOptions и затем передаете возможно сцепленные значения перечисления, чтобы FrameworkPropertyMetadata конструктор. Тем не менее, после создания эти характеристики параметра представляются в FrameworkPropertyMetadata как ряд логических свойств, а не как созданные значения перечисления. Логические свойства позволяют проверить каждое условие, а не требуют применения маски к значению флагового перечисления для получения интересующей вас информации. Конструктор использует объединенные FrameworkPropertyMetadataOptions чтобы сократить длину подписи конструктора приемлемой, тогда как фактически построенные метаданные предоставляют дискретные свойства, чтобы сделать запрос метаданных более понятным.
Когда следует переопределять метаданные, а когда — создавать производный класс
В системном свойстве WPF имеются установленные возможности для изменения некоторых характеристик свойств зависимости без повторного создания с нуля. Это достигается путем создания другого экземпляра метаданных свойства для свойства зависимости в том виде, в котором оно существует в определенном типе. Обратите внимание, что большинство существующих свойств зависимости не являются виртуальными свойствами, поэтому строго говоря, их повторное создание в унаследованных классах возможно только путем затемнения существующего члена.
Если невозможно реализовать нужный вам сценарий для свойства зависимости в типе путем изменения характеристик существующих свойств зависимости, возможно, потребуется создать производный класс, а затем объявить в нем пользовательское свойство зависимости. Пользовательское свойство зависимости ведет себя идентично свойствам зависимости, определенным WPF API. Дополнительные сведения о пользовательских свойствах зависимости см. в разделе Пользовательские свойства зависимости.
Единственной важной характеристикой свойства зависимости, которую невозможно переопределить, является его тип значения. Если вы наследуете свойство зависимости, которое имеет примерное поведение, нужное вам, но вам нужен другой тип свойства, потребуется создать пользовательское свойство зависимости и, возможно, связать два свойства друг с другом через преобразование типов или другую реализацию пользовательского класса. Кроме того, невозможно заменить существующий ValidateValueCallback, так как этот обратный вызов существует в поле регистрации и не входит в метаданные.
Сценарии для изменения существующих метаданных
При работе с метаданными существующего свойства зависимости одним из распространенных сценариев для изменения метаданных свойства зависимости является изменение значения по умолчанию. Изменение или добавление обратных вызовов системы свойств является более сложным сценарием. Это целесообразно, если в вашей реализации производного класса существуют различные взаимосвязи между свойствами зависимостей. Одно из условий наличия модели программирования, которая поддерживает и код, и декларативное использование, заключается в том, что свойства должны обеспечить возможность настройки их значений в любом порядке. Следовательно, все зависимые свойства необходимо настраивать в режиме JIT без контекста; при этом невозможно использовать какую-либо информацию о порядке настройки (которую можно найти, например, в конструкторе). Дополнительные сведения об этом аспекте системы свойств см. в разделе Проверка и обратные вызовы свойства зависимостей. Обратите внимание, что обратные вызовы проверки не являются частью метаданных; они являются частью идентификатора свойства зависимости. Следовательно, обратные вызовы проверки невозможно изменить путем переопределения метаданных.
В некоторых случаях целесообразно изменить параметры метаданных свойств уровня среды WPF для существующих свойств зависимости. Эти параметры связывают некоторые известные условия свойств уровня среды WPF с другими процессами среды WPF, такими как система макетов. Настройка параметров обычно выполняется только в том случае, при регистрации нового свойства зависимости, но это также можно изменить метаданные свойства уровня среды WPF как часть OverrideMetadata или AddOwner вызова. Дополнительные сведения и рекомендации по использованию конкретных значений см. в разделе Метаданные свойств среды. Дополнительные сведения о том, как следует настраивать эти свойства для только что зарегистрированного свойства зависимости, см. в разделе Пользовательские свойства зависимости.
Переопределение метаданных
Основной целью переопределения метаданных является то, что у вас есть возможность изменить различные производные от метаданных характеристики, которые применяются к свойству зависимости в том виде, в котором оно существует в вашем типе. Причины этого рассматриваются более подробно в разделе Метаданные. Дополнительные сведения, включая примеры кода, см. в разделе Переопределение метаданных для свойства зависимости.
Метаданные свойства для свойства зависимостей можно указать во время вызова регистрации (Register). Но во многих случаях целесообразно предоставить метаданные определенного типа для вашего класса, когда он наследует соответствующее свойство зависимости. Это можно сделать, вызвав OverrideMetadata метод. Пример из WPF API, 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. Если вложенное свойство задано в экземпляре класса, действуют характеристики переопределенных метаданных свойства. Например, можно переопределить значение по умолчанию, чтобы переопределенное значение передавалось как значение вложенного свойства в экземплярах класса всякий раз, когда свойство не задано никаким другим способом.
Note
Inherits Свойство не применимо для присоединенных свойств.
Добавление класса в качестве владельца существующего свойства зависимости
Класс может добавить себя в качестве владельца свойства зависимостей, которое уже зарегистрировано, с помощью AddOwner метод. Это позволяет классу использовать свойство зависимости, первоначально зарегистрированное для другого типа. Добавляемый класс, как правило, не является производным классом типа, который первым зарегистрировал это свойство зависимости в качестве владельца. Фактически это позволяет классу и его производным классам "наследовать" реализацию свойства зависимости, даже если исходный класс-владелец и добавляемый класс не находятся в одной действительной иерархии классов. Кроме того, добавляемый класс (и все его наследуемые классы) могут затем предоставить метаданные определенного типа для исходного свойства зависимости.
Помимо добавления себя в качестве владельца с использованием служебных методов системы свойств, добавляемый класс должен объявить в себе дополнительные открытые элементы, чтобы сделать свойство зависимости полноценным участником в системе свойств, которое доступно и коду, и разметке. Класс, который добавляет существующее свойство зависимости, имеет те же обязанности по предоставлению объектной модели для свойства зависимости, что и класс, определяющий новое пользовательское свойство зависимости. Первый такой предоставляемый элемент — поле идентификатора свойства зависимости. Это поле должно быть public static readonly
поле типа DependencyProperty, которому присваивается значение, возвращаемое AddOwner вызова. Вторым определяемым элементом является свойство "программы-оболочки" CLR. Оболочка делает гораздо удобнее управлять свойством зависимости в коде (Избегайте вызовов SetValue каждый раз и достаточно сделать соответствующий вызов однократно в самой программе-оболочке). Оболочка реализуется так же, как если бы регистрировалось пользовательское свойство зависимости. Дополнительные сведения о реализации свойства зависимости см. в разделе Пользовательские свойства взаимозависимости и Добавление типа владельца для свойства зависимостей.
AddOwner и вложенные свойства
Вы можете вызвать AddOwner для свойства зависимостей, определенный классом-владельцем как вложенное свойство. Обычно так делают, чтобы предоставить ранее вложенное свойство в качестве невложенного свойства зависимости. Затем будет предоставлять AddOwner возвратить значение public static readonly
поле для использования в качестве идентификатора свойства зависимости и будут определены соответствующие «оболочки» свойства, чтобы свойство появится в таблице элементов и поддерживает невложенного свойства Использование в вашем классе.