wpf - Dependency Property Value Precedence

A dependency property to an DependencyObject may get its value from various source, the type of sources that the DependencyProperty may get include 

 

  • Default
  • DefaultStyle
  • DefaultTrigger
  • Style
  • ...
  • Local
The value  of such sources are identified in those sources BaseValueSource ;

Quote from the MSDN documentation:

Each value of this enumeration indicates that a particular aspect of the overall WPF property system was responsible for the effective value determination of a certain dependency property value on a specific dependency object. To learn more about the WPF property system and the precedence at which each aspect of the property system operates, see  Dependency Property Value Precedence .

Leading from the article Dependency Properties Overview , and we followed to the topic of Dependency Property Value Precedence, where explains the working of the Windows Presentation Foundataion (WPF) property system can affect the value of dependency Property,  and describes the precedence by which aspects of the property system apply to the effective value of a property.


Below is the official list of rule to determine the precedence of list; I excerpt it here to make it convenietn for user to reference. 

<quote>
The following is the definitive order that the property system uses when assigning the run-time values of dependency properties. Highest precedence is listed first. This list expands on some of the generalizations made in the  Dependency Properties Overview .

  1. Property system coercion. For details on coercion, see Coercion, Animation, and Base Value later in this topic.

  2. Active animations, or animations with a Hold behavior. In order to have any practical effect, an animation of a property must be able to have precedence over the base (unanimated) value, even if that value was set locally. For details, see Coercion, Animation, and Base Value later in this topic.

  3. Local value. A local value might be set through the convenience of the "wrapper" property, which also equates to setting as an attribute or property element in XAML, or by a call to theSetValue API using a property of a specific instance. If you set a local value by using a binding or a resource, these each act in the precedence as if a direct value was set.

  4. TemplatedParent template properties. An element has a TemplatedParent if it was created as part of a template (a ControlTemplate or DataTemplate). For details on when this applies, seeTemplatedParent later in this topic. Within the template, the following precedence applies:

    1. Triggers from the TemplatedParent template.

    2. Property sets (typically through XAML attributes) in the TemplatedParent template.

  5. Implicit style. Applies only to the Style property. The Style property is filled by any style resource with a key that matches the type of that element. That style resource must exist either in the page or the application; lookup for an implicit style resource does not proceed into the themes.

  6. Style triggers. The triggers within styles from page or application (these styles might be either explicit or implicit styles, but not from the default styles, which have lower precedence).

  7. Template triggers. Any trigger from a template within a style, or a directly applied template.

  8. Style setters. Values from a Setter within styles from page or application.

  9. Default (theme) style. For details on when this applies, and how theme styles relate to the templates within theme styles, see Default (Theme) Styles later in this topic. Within a default style, the following order of precedence applies:

    1. Active triggers in the theme style.

    2. Setters in the theme style.

  10. Inheritance. A few dependency properties inherit their values from parent element to child elements, such that they need not be set specifically on each element throughout an application. For details see Property Value Inheritance.

  11. Default value from dependency property metadata. Any given dependency property may have a default value as established by the property system registration of that particular property. Also, derived classes that inherit a dependency property have the option to override that metadata (including the default value) on a per-type basis. See Dependency Property Metadata for more information. Because inheritance is checked before default value, for an inherited property, a parent element default value takes precedence over a child element. Consequently, if an inheritable property is not set anywhere, the default value as specified on the root or parent is used instead of the child element default value.

     

</quote>

I would strongly recommend readers to have a close look at the article of Dependency Property Value Precedence.

Below I will show some of the techniques regaring either get the ValueSource, BaseValueSource and etc..

Get ValueSource of an DependencyProperty of an DependencyObject;

    // GetValueSource
    //  get the value reports various metadata property system characteristics of a specific dependency Property on a particular DependencyObject
    public static ValueSource GetValueSource(FrameworkElement item, DependencyProperty prop)
    {
      // what if the item does not have teh item property 
      if (item == null) throw new ArgumentNullException("item");
      if (prop == null) throw new ArgumentNullException("prop");
      // we assume if we cannot get MetaData about a particular DependencyProperty from an FrameworkElement, then 
      // the FrameworkElement does not have that particular property 
      if (prop.GetMetadata(item) == null) throw new ArgumentException(string.Format("item does not have Dependency property {0}", prop.Name));

      ValueSource valueSource = DependencyPropertyHelper.GetValueSource(item, prop);
      return valueSource;
    }
 
and from the ValueSource, you can further inspect the value of BaseValueSource, in additional to other properties such as IsCurrent, IsCoerced, IsAnimated, IsExpression or etc...


    // GetBaseValueSource
    //  get the ValueSource identify the source of a particular dependency value
    public static BaseValueSource GetBaseValueSource(FrameworkElement item, DependencyProperty prop)
    {
      var valueSource = GetValueSource(item, prop);
      return valueSource.BaseValueSource;
    }
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值