WPF中的PropertyMetaData,UIPropertyMetadata和FrameworkMetaData之间有什么区别

时间:2013-01-08 18:27:36

标签: wpf

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

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

提前致谢。

3 个答案:

答案 0 :(得分:11)

来源:PropertyMetadata vs. FrameworkPropertyMetadata

  

当您implement a custom dependency property并通过调用DependencyProperty.Register注册该属性时,您可以通过向其传递PropertyMetadata的实例来为该属性指定一些元数据。这可以是PropertyMetadata类的实例,也可以是其子类之一的实例。差异如下所示。

     

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

     
      
  • CoerceValueCallback - 设置时强制设置值
  •   
  • DefaultValue - 属性的默认值
  •   
  • PropertyChangedCallback - 回应房产的新有效价值
  •   
     

UIPropertyMetadata - 来自PropertyMetadata并添加:

     
      
  • IsAnimationProhibited - 停用此属性的动画?
  •   
     

FrameworkPropertyMetadata - 来自UIPropertyMetadata并添加:

     
      
  • AffectsArrangeAffectsMeasureAffectsParentArrangeAffectsParentMeasureAffectsRender - 是否应在属性值更改后重新运行布局计算?
  •   
  • BindsTwoWayByDefaultDefaultUpdateSourceTriggerIsDataBindingAllowedIsNotDataBindable - 指示财产如何参与数据绑定
  •   
  • InheritsOverridesInheritanceBehavior - 继承是否适用于此属性?
  •   
  • Journal - 在日记时存储此值?
  •   
  • SubPropertiesDoNotAffectRender - 在布局更改时检查此对象的属性?
  •   

答案 1 :(得分:5)

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

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

答案 2 :(得分:1)

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

还要注意,所有三个FrameworkPropertyMetadata声明的属性如何相互作用。也就是说,IsDataBindingAllowed!IsNotDataBindable 不是 相同;前者增加了额外的限制,即排除了对“只读”属性使用错误的绑定 direction 的可能性。

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