WPF中PropertyMetaData、UIPropertyMetadata和FrameworkMetaData的区别是什么?

13
我了解这些类之间的基本区别,PropertyMetadata用于备份属性,UIPropertyMetadata用于支持动画,FrameworkMetadata用于在用户控件中使用框架属性。
但我只理解理论部分。如果您能提供一个最简单的示例,使用这3个不同依赖属性的类,明确区分它们,那将是非常有帮助的。
谢谢提前。

你可以轻松地创建3个依赖属性并观察结果。如果你仍然有特定的问题,请来提问。 - Benjamin Gale
我刚开始尝试使用依赖属性。但是为了熟悉这三个类,我正在寻找一个简单的例子,如果你能写出并解释一下,那对我来说会非常有帮助。谢谢。 - WpfBee
1
http://wpf.2000things.com/2012/06/07/575-propertymetadata-vs-frameworkpropertymetadata/ - eran otzap
3个回答

19

来源:PropertyMetadata与FrameworkPropertyMetadata

当你实现自定义依赖属性并通过调用DependencyProperty.Register注册该属性时,你需要传递一个PropertyMetadata的实例来指定一些属性元数据。这可以是PropertyMetadata类的实例或其子类的实例。具体区别如下:

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

  • CoerceValueCallback – 在设置值时强制执行的回调函数
  • DefaultValue – 属性的默认值
  • PropertyChangedCallback – 对属性的新有效值做出响应的回调函数

UIPropertyMetadata – 派生自PropertyMetadata并添加了以下内容:

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

FrameworkPropertyMetadata – 派生自UIPropertyMetadata并添加了以下内容:

  • AffectsArrangeAffectsMeasureAffectsParentArrangeAffectsParentMeasureAffectsRender – 在属性值更改后是否重新运行布局计算?
  • BindsTwoWayByDefaultDefaultUpdateSourceTriggerIsDataBindingAllowedIsNotDataBindable – 指定属性在数据绑定中的参与方式
  • InheritsOverridesInheritanceBehavior - 这个属性是否支持继承?
  • Journal - 在记录日志时是否存储此值?
  • SubPropertiesDoNotAffectRender - 当布局更改时,是否检查此对象的属性?

  • 5

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

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


    1

    FrameworkPropertyMetadataUIPropertyMetadata暴露的所有行为都由标志位控制,这些标志位记录在单个enum(32位uint字段_flags中,该字段声明在PropertyMetadata基类中,尽管其中没有任何标志位被公开。以下是该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
    };
    注意以下三个属性,它们都是由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
    };
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接