property engine precedence (part 2)

2.2 Expressions -- Dynamic resources and data binding
{Binding} and {DynamicResource} both create instances of Expression.  In a lot of ways, Expressions are just another kind of value for the WPF property engine to deal with.  You can pass them into SetValue(dp, expression), and <Setter> can specify an expression, and almost all of the base value precedence stages support expressions.  (Default value being a notable exception)

Expressions are different from other values because the property engine (e.g., GetValue) doesn’t normally return it to you, it evaluates the expression and returns the result of that.  So GetValue will evaluate the data binding or find the resource.

Data binding can sometimes take a while to compute the “complete” answer.  So under certain circumstances, when the property engine evaluates the BindingExpression, BindingExpression returns the old value, and after the property engine is done and the dispatcher gets back to dispatching, the complete answer is calculated.
2.3 Animated Value
The above search only determines the property’s “base” value.  If the property is also being animated, then this base value is modified by the animation.  Take this example:

<Window>
 ...
 <Button Name=”myButton” Width=”100” Content=”Click”>
  <Button.Triggers>
   <EventTrigger RoutedEvent=”Button.Click” >
    <BeginStoryboard TargetProperty=”(Button.Width)”>
     <Storyboard>
      <DoubleAnimation To=”200”/>
     </Storyboard>
    </BeginStoryboard>
   </EventTrigger>
  </Button.Triggers>
 </Button>
 ...
</Window>

Here, myButton.Width will first use the above rules to calculate a base value for the WidthProperty of 100 (the locally set value).  Then it will apply an animation to 100 that as a “To” but no “From”.  So the animation will implicitly use the base value as the “From”, and in the end will animate from 100 to 200.

But if you change the DoubleAnimation to:


<DoubleAnimation From=”150” To=”200” />

Then the animation will override the base value, the 100 will be ignored, and the Width will animate from 150 to 200.

If the animation contains an expression (e.g. <DoubleAnimation From=”{Binding…}”/>, the expression is evaluated once when the animation begins, and is not reevaluated during the life of the animation.
2.4 Coercion (CoerceValueCallback)
As the final stage in property calculation, the value is potentially coerced.  Coercion enables the Scrollbar’s Min/Max/Value properties – where the properties can be set in any order, and Value will always returned a value between Min and Max, even if someone set Value to something much greater than Max.

After CoerceValueCallback is called, ValidateValueCallback is called on that value, and the property engine will throw an exception and be left in any invalid state if the value is not valid.