5

我们需要DependencyProperty为我们的子类覆盖 a 的元数据。现在我知道我可以使用OverrideMetadata和指定全新的FrameworkPropertyMetadata对象,但在大多数情况下,我希望这个新元数据与现有元数据完全相同,除了设置了一个额外的标志(特别是AffectsMeasure

我的想法是获取现有的元数据,创建一个新的元数据对象,将所有成员从旧的手动复制到新的(它不支持Clone)更改我想要的,然后在 OverrideMetadata 调用中使用新的. 但是 da** 对于原本如此简单的事情来说,这是很多工作!

我在这里错过了什么吗?

编辑

首先,我的意思AffectsMeasure不是AffectsRender(我在上面已经改变了),

但是...我刚刚发现我们的班级已经为该属性设置了AffectsMeasure标志。Width真正的问题是对于 a ListBox(例如 a ListBoxItem)的容器,它MeasureOverride在第一次初始化时只被调用一次。

由于这在技术上是一个不相关的问题,我将开始一个新问题并关闭这个问题。

这是新问题的链接:

为什么 ListBoxItem 在宽度改变时不调用 MeasureOverride?

4

1 回答 1

2

从基类的元数据复制元数据绝对是要走的路。尽管不幸的是,FrameworkPropertyMetadata该类并没有像给出的那样公开标志,但它们作为bool属性公开以指示它们的状态。要将这些值作为 a 返回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;
}
于 2011-10-04T06:47:42.610 回答