Как мога да променя само една опция от метаданните на DependencyProperty в подклас?

Трябва да заменим метаданните на DependencyProperty за нашия подклас. Сега знам, че мога да използвам OverrideMetadata и да посоча изцяло нов обект FrameworkPropertyMetadata, но в по-голямата си част искам тези нови метаданни да бъдат точно същите като съществуващите метаданни, освен с един допълнителен набор от флагове (по-специално AffectsMeasure)

Мисълта ми е да получа съществуващите метаданни, да създам нов обект с метаданни, да копирам ръчно всички членове от стария в новия (той не поддържа Clone), променяйки този, който искам, след това да използвам новия в OverrideMetadata обадете се. Но, да**, това е много работа за нещо иначе толкова просто!

Пропускам ли нещо тук?

РЕДАКТИРАНЕ

Първо, имах предвид AffectsMeasure не AffectsRender (което промених по-горе),

НО... току-що разбрах, че нашият клас вече има зададен флаг AffectsMeasure за свойството Width. Истинският проблем е, че за контейнери на ListBox (напр. ListBoxItem) MeasureOverride се извиква само веднъж, когато се инициализира за първи път.

Тъй като технически това е несвързан въпрос, ще започна нов и ще затворя този.

Ето връзката към новия въпрос:

Защо ListBoxItem не извиква MeasureOverride, когато ширината му се промени?


person Mark A. Donohoe    schedule 04.10.2011    source източник
comment
Здравейте, това, което можете да направите, е да извикате InvalidateVisual в рамките на вашия манипулатор на събитие за промяна на стойността на DP, което за мен е по-чист начин за това.   -  person    schedule 04.10.2011


Отговори (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;
}
person Jeff Mercado    schedule 04.10.2011
comment
Разглеждайки изпълнението на FrameworkPropertyMetadata, то поддържа друго състояние, така че клонирането като цяло вероятно не би било добра идея. - person Jeff Mercado; 04.10.2011
comment
Така или иначе не поддържа „клонинг“. НО... оказва се, че това не е проблемът. Публикувам нов въпрос, свързан с това, с което си имаме работа, което е ListBoxItem, който се преоразмерява, но който не извиква вътрешно MeasureOverride, въпреки че този флаг е зададен за свойството Width и ние не знаем защо. - person Mark A. Donohoe; 05.10.2011