我知道这些类之间的基本区别是,当我们备份属性时使用 PropertyMetadata,当我们想要支持动画时使用 UIPropertyMetadata,以及在用户控件中使用框架属性时使用 FrameworkMetadata。
但我只了解理论部分。如果您解释一个使用所有这 3 个类在 3 个不同的依赖属性中清楚地区分它们的最简单示例,那将是一个很好的帮助。
提前致谢。
我知道这些类之间的基本区别是,当我们备份属性时使用 PropertyMetadata,当我们想要支持动画时使用 UIPropertyMetadata,以及在用户控件中使用框架属性时使用 FrameworkMetadata。
但我只了解理论部分。如果您解释一个使用所有这 3 个类在 3 个不同的依赖属性中清楚地区分它们的最简单示例,那将是一个很好的帮助。
提前致谢。
资料来源:PropertyMetadata 与 FrameworkPropertyMetadata
当您实现自定义依赖属性并通过调用注册该属性时
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– 当布局改变时检查这个对象的属性?
PropertyMetadata 和 FrameworkPropertyMetadata 之间的一个重要实际区别是后者允许指定一组FrameworkPropertyMetadataOptions。
例如,指定FrameworkPropertyMetadataOptions.AffectsRender关心启动属性已更改的 UIElement 的重新呈现。如果没有此标志,您将不得不在 PropertyChangedCallback 中手动执行此操作。
所有的行为都由记录在基类中声明的单个(32 位)字段中的标志位公开FrameworkPropertyMetadata并由其控制,即使没有任何标志实际上是从那里公开公开的。这是该声明:UIPropertyMetadataenumuint_flagsPropertyMetadataenum
内部枚举 MetadataFlags : uint
{
 DefaultValueModifiedID /**/= 0b_00000000_00000000_00000000_00000001, //0x00000001
 SealedID /**/= 0b_00000000_00000000_00000000_00000010, //0x00000002
 继承 /**/= 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
};
还要注意以下三个属性(均由 声明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;
FrameworkPropertyMetadataOptions标志指定的值不同!
[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
};