Как я могу изменить только один параметр метаданных 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;
}
Другие вопросы по тегам