Как я могу изменить только один параметр метаданных DependencyProperty в подклассе?
Нам нужно переопределить DependencyProperty
метаданные для нашего подкласса. Теперь я знаю, что я могу использовать OverrideMetadata
и указать совершенно новый FrameworkPropertyMetadata
объект, но по большей части я хочу, чтобы эти новые метаданные были точно такими же, как существующие метаданные, за исключением одного дополнительного установленного флага (в частности, AffectsMeasure
)
Моя мысль состоит в том, чтобы получить существующие метаданные, создать новый объект метаданных, вручную скопировать все элементы из старого в новый (он не поддерживает Clone
) измените тот, который я хочу, затем используйте новый в вызове OverrideMetadata. Но да ** это много работы для чего-то такого простого!
Я что-то здесь упускаю?
РЕДАКТИРОВАТЬ
Обо всем по порядку AffectsMeasure
не AffectsRender
(который я изменил выше),
НО... Я только что узнал, что в нашем классе уже есть AffectsMeasure
флаг установлен для Width
имущество. Настоящая проблема заключается в контейнерах ListBox
(например, ListBoxItem
) MeasureOverride
вызывается только один раз при первой инициализации.
Поскольку это технически не связанный вопрос, я начну новый и закрою этот.
Вот ссылка на новый вопрос:
Почему ListBoxItem не вызывает MeasureOverride при изменении его ширины?
1 ответ
Копирование метаданных из метаданных базового класса - это определенно правильный путь. Хотя, к сожалению, FrameworkPropertyMetadata
класс не выставляет флаги как они даны, они выставляются как bool
свойства, чтобы указать их состояние. Чтобы вернуть эти значения как FrameworkPropertyMetadataOptions
Вам нужно будет просмотреть связанные свойства и прочитать их обратно как единое целое.
static DerivedClass()
{
var oldMeta = (FrameworkPropertyMetadata)BaseClass.SomeProperty.GetMetadata(typeof(BaseClass));
var flags = GetFlags(oldMeta);
// change the values as needed
var meta = new FrameworkPropertyMetadata(
oldMeta.DefaultValue,
flags,
oldMeta.PropertyChangedCallback,
oldMeta.CoerceValueCallback,
oldMeta.IsAnimationProhibited,
oldMeta.DefaultUpdateSourceTrigger
);
BaseClass.SomeProperty.OverrideMetadata(typeof(DerivedClass), meta);
}
static FrameworkPropertyMetadataOptions GetFlags(FrameworkPropertyMetadata metadata)
{
FrameworkPropertyMetadataOptions flags = FrameworkPropertyMetadataOptions.None;
if (metadata.AffectsArrange)
flags |= FrameworkPropertyMetadataOptions.AffectsArrange;
if (metadata.AffectsMeasure)
flags |= FrameworkPropertyMetadataOptions.AffectsMeasure;
if (metadata.AffectsParentArrange)
flags |= FrameworkPropertyMetadataOptions.AffectsParentArrange;
if (metadata.AffectsParentMeasure)
flags |= FrameworkPropertyMetadataOptions.AffectsParentMeasure;
if (metadata.AffectsRender)
flags |= FrameworkPropertyMetadataOptions.AffectsRender;
if (metadata.BindsTwoWayByDefault)
flags |= FrameworkPropertyMetadataOptions.BindsTwoWayByDefault;
if (metadata.Inherits)
flags |= FrameworkPropertyMetadataOptions.Inherits;
if (metadata.Journal)
flags |= FrameworkPropertyMetadataOptions.Journal;
if (metadata.IsNotDataBindable)
flags |= FrameworkPropertyMetadataOptions.NotDataBindable;
if (metadata.OverridesInheritanceBehavior)
flags |= FrameworkPropertyMetadataOptions.OverridesInheritanceBehavior;
if (metadata.SubPropertiesDoNotAffectRender)
flags |= FrameworkPropertyMetadataOptions.SubPropertiesDoNotAffectRender;
return flags;
}