开发者

How can I change only a single option of a DependencyProperty's metadata in a subclass?

We need to override a DependencyProperty's metadata for our subclass. Now I know that I can use OverrideMetadata and specify entirely new FrameworkPropertyMetadata object, but for the most part I want开发者_Go百科 this new metadata to be exactly the same as the existing metadata except with one additional flag set (specifically AffectsMeasure)

My thought is to get the existing metadata, create a new metadata object, hand-copy all the members over from the old to the new (it doesn't support Clone) changing the one I want, then use the new one in the OverrideMetadata call. But da** that is a lot of work for something otherwise so simple!

Am I missing something here?

EDIT

First things first, I meant AffectsMeasure not AffectsRender (which I've changed above),

BUT... I just found out our class already has the AffectsMeasure flag set for the Width property. The real issue is for containers of a ListBox (e.g. a ListBoxItem) the MeasureOverride is only called once, when first initialized.

Since this is technically an unrelated question, I'll start a new one and close this one.

Here's the link to the new question:

Why is a ListBoxItem not calling MeasureOverride when its width is changed?


Copying the metadata from the base class' metadata is definitely the way to go. Though unfortunately the FrameworkPropertyMetadata class doesn't expose the flags as they given, they are exposed as bool properties to indicate their state. To get those values back as a FrameworkPropertyMetadataOptions, you'll have to go through the associated properties and read them back as one.

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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜