wpf WPF中的PropertyMetaData、UIPropertyMetadata、FrameworkMetaData有什么区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14221636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 06:57:30  来源:igfitidea点击:

What are the differences among PropertyMetaData, UIPropertyMetadata, and FrameworkMetaData in WPF

wpf

提问by WpfBee

I know the basic difference among these classes that PropertyMetadata is used when we backup property, UIPropertyMetadata when we want to have support for animation, and FrameworkMetadata for Framework properties to be used in user controls.

我知道这些类之间的基本区别,当我们备份属性时使用 PropertyMetadata,当我们想要支持动画时使用 UIPropertyMetadata,以及要在用户控件中使用的框架属性的 FrameworkMetadata。

But I understand theoretical part only. It will be a great hep if you please explain a simplest example that uses all these 3 classes in 3 different dependency properties distinguishing them clearly.

但我只了解理论部分。如果你能解释一个最简单的例子,在 3 个不同的依赖属性中使用所有这 3 个类来清楚地区分它们,那将是一个很好的例子。

Thanks in advance.

提前致谢。

回答by Muthuganesh

Source: PropertyMetadata vs. FrameworkPropertyMetadata

来源:PropertyMetadata 与 FrameworkPropertyMetadata

When you implement a custom dependency propertyand you register the property by calling DependencyProperty.Register, you specify some metadata for the property by passing it an instance of PropertyMetadata. This can be an instance of the PropertyMetadataclass or an instance of one of its subclasses. The differences are shown below.

PropertyMetadata– Basic metadata relating to dependency properties

  • CoerceValueCallback– coerce the value when being set
  • DefaultValue– a default value for the property
  • PropertyChangedCallback– respond to new effective value for the property

UIPropertyMetadata– derives from PropertyMetadataand adds:

  • IsAnimationProhibited– disable animations for this property?

FrameworkPropertyMetadata– derives from UIPropertyMetadataand adds:

  • AffectsArrange, AffectsMeasure, AffectsParentArrange, AffectsParentMeasure, AffectsRender– Should layout calculations be re-run after property value changes?
  • BindsTwoWayByDefault, DefaultUpdateSourceTrigger, IsDataBindingAllowed, IsNotDataBindable– Dictates how property participates in data binding
  • Inherits, OverridesInheritanceBehavior– Does inheritance work for this property?
  • Journal– Store this value when journaling?
  • SubPropertiesDoNotAffectRender– Check properties of this object when layout changes?

当您实现自定义依赖项属性并通过调用注册该属性时DependencyProperty.Register,您可以通过将PropertyMetadata. 这可以是PropertyMetadata类的实例,也可以是其子类之一的实例。差异如下所示。

PropertyMetadata– 与依赖属性相关的基本元数据

  • CoerceValueCallback– 设置时强制值
  • DefaultValue– 属性的默认值
  • PropertyChangedCallback– 响应该物业的新有效价值

UIPropertyMetadata– 源自PropertyMetadata并补充:

  • IsAnimationProhibited– 禁用此属性的动画?

FrameworkPropertyMetadata– 源自UIPropertyMetadata并补充:

  • AffectsArrange, AffectsMeasure, AffectsParentArrange, AffectsParentMeasure, AffectsRender– 属性值更改后是否应重新运行布局计算?
  • BindsTwoWayByDefault, DefaultUpdateSourceTrigger, IsDataBindingAllowed, IsNotDataBindable– 规定属性如何参与数据绑定
  • Inherits, OverridesInheritanceBehavior– 继承对这个属性有效吗?
  • Journal– 记录时存储此值?
  • SubPropertiesDoNotAffectRender– 当布局改变时检查这个对象的属性?

回答by Clemens

An important practical difference between PropertyMetadata and FrameworkPropertyMetadata is that the latter allows to specify a set of FrameworkPropertyMetadataOptions.

PropertyMetadata 和 FrameworkPropertyMetadata 之间的一个重要的实际区别是后者允许指定一组FrameworkPropertyMetadataOptions

For example, specifying FrameworkPropertyMetadataOptions.AffectsRendercares for initiating a re-rendering of a UIElement on which the property has changed. Without this flag you would have to do that manually in a PropertyChangedCallback.

例如,指定FrameworkPropertyMetadataOptions.AffectsRender关心启动属性已更改的 UIElement 的重新呈现。如果没有此标志,您将必须在 PropertyChangedCallback 中手动执行此操作。

回答by Glenn Slayden

All of the behaviors exposed by FrameworkPropertyMetadataand UIPropertyMetadataare controlled by flag bits that are recorded in a single enum(32-bit uint) fieldcalled _flagswhich is declared in the PropertyMetadatabase class, even though none of the flags are actually publicly exposed from there. Here is the declaration of that enum:

所有行为的暴露由FrameworkPropertyMetadataUIPropertyMetadata由被记录在一个单一的标志位被控制enum(32位uint字段称为_flags其在声明的PropertyMetadata基类,即使没有标志位实际上公开从那里露出。这是声明enum

internal enum MetadataFlags : uint
{
 DefaultValueModifiedID                 /**/= 0b_00000000_00000000_00000000_00000001, //0x00000001
 SealedID                               /**/= 0b_00000000_00000000_00000000_00000010, //0x00000002
 Inherited                              /**/= 0b_00000000_00000000_00000000_00010000, //0x00000010
 UI_IsAnimationProhibitedID             /**/= 0b_00000000_00000000_00000000_00100000, //0x00000020
 FW_AffectsMeasureID                    /**/= 0b_00000000_00000000_00000000_01000000, //0x00000040
 FW_AffectsArrangeID                    /**/= 0b_00000000_00000000_00000000_10000000, //0x00000080
 FW_AffectsParentMeasureID              /**/= 0b_00000000_00000000_00000001_00000000, //0x00000100
 FW_AffectsParentArrangeID              /**/= 0b_00000000_00000000_00000010_00000000, //0x00000200
 FW_AffectsRenderID                     /**/= 0b_00000000_00000000_00000100_00000000, //0x00000400
 FW_OverridesInheritanceBehaviorID      /**/= 0b_00000000_00000000_00001000_00000000, //0x00000800
 FW_IsNotDataBindableID                 /**/= 0b_00000000_00000000_00010000_00000000, //0x00001000
 FW_BindsTwoWayByDefaultID              /**/= 0b_00000000_00000000_00100000_00000000, //0x00002000
 FW_ShouldBeJournaledID                 /**/= 0b_00000000_00000000_01000000_00000000, //0x00004000
 FW_SubPropertiesDoNotAffectRenderID    /**/= 0b_00000000_00000000_10000000_00000000, //0x00008000
 FW_SubPropertiesDoNotAffectRenderModifiedID= 0b_00000000_00000001_00000000_00000000, //0x00010000
 FW_InheritsModifiedID                  /**/= 0b_00000000_00010000_00000000_00000000, //0x00100000
 FW_OverridesInheritanceBehaviorModifiedID  = 0b_00000000_00100000_00000000_00000000, //0x00200000
 FW_ShouldBeJournaledModifiedID         /**/= 0b_00000001_00000000_00000000_00000000, //0x01000000
 FW_UpdatesSourceOnLostFocusByDefaultID /**/= 0b_00000010_00000000_00000000_00000000, //0x02000000
 FW_DefaultUpdateSourceTriggerModifiedID/**/= 0b_00000100_00000000_00000000_00000000, //0x04000000
 FW_ReadOnlyID                          /**/= 0b_00001000_00000000_00000000_00000000, //0x08000000
 FW_DefaultUpdateSourceTriggerEnumBit1  /**/= 0b_01000000_00000000_00000000_00000000, //0x40000000
 FW_DefaultUpdateSourceTriggerEnumBit2  /**/= 0b_10000000_00000000_00000000_00000000, //0x80000000
};

Note also how the following three properties, all declared by FrameworkPropertyMetadata, interact. To wit, IsDataBindingAllowedis notthe same as !IsNotDataBindable; the former adds the additional restriction of ruling out the use of the incorrect binding directionfor 'read-only' properties.

另请注意以下三个属性(均由 声明)如何FrameworkPropertyMetadata交互。要机智,IsDataBindingAllowed一样的!IsNotDataBindable; 前者增加了排除对“只读”属性使用错误绑定方向的额外限制。

private bool ReadOnly => (_flags & FW_ReadOnlyID) != 0;

public bool IsDataBindingAllowed =>
                     (_flags & FW_IsNotDataBindableID) == 0 && !this.ReadOnly;

public bool IsNotDataBindable => (_flags & FW_IsNotDataBindableID) != 0;






[edit:][编辑:]警报/警告:由于某些未知原因,上面显示的标志确实not共享与相应FrameworkPropertyMetadataOptionsFrameworkPropertyMetadataOptions标志指定的值相同的值!

[Flags]
public enum FrameworkPropertyMetadataOptions
{                                  //         FPMO            MetadataFlags
                                   //     ----------           ----------
                                   //                          0x00000010 ←┐
    None                           /**/ = 0x00000000, //                   │
    AffectsMeasure                 /**/ = 0x00000001, //  << 6 0x00000040  │
    AffectsArrange                 /**/ = 0x00000002, //  << 6 0x00000080  │
    AffectsParentMeasure           /**/ = 0x00000004, //  << 6 0x00000100  │
    AffectsParentArrange           /**/ = 0x00000008, //  << 6 0x00000200  │
    AffectsRender                  /**/ = 0x00000010, //  << 6 0x00000400  │
    Inherits                       /**/ = 0x00000020, //  >> 1   →  →  ────┘
    OverridesInheritanceBehavior   /**/ = 0x00000040, //  << 5 0x00000800
    NotDataBindable                /**/ = 0x00000080, //  << 5 0x00001000
    BindsTwoWayByDefault           /**/ = 0x00000100, //  << 5 0x00002000
    Journal                        /**/ = 0x00000400, //  << 4 0x00004000
    SubPropertiesDoNotAffectRender /**/ = 0x00000800, //  << 4 0x00008000
};