DependencyProperty Precedence(2)

One common question is that: Why can’t change the DependencyProperty value after applying animation with a hold behavior and how to solve it?

I have create a simple solution to go deep on coercion, animation and local value. You can download it by clicking following link. (it’s on Microsoft SkyDriver.)

In this solution, there are 2 projects.

Let’s focused on the WpfAnimationAndLocalValue project first(Another project will explained in the next post)

The snapshot of this program:

Main

There are 4 buttons you can click:

“Start animation” button(Button 1) :

    1: private void StartAnimation(object sender, RoutedEventArgs e)
    2: {
    3:     DoubleAnimation doubleAnimation = new DoubleAnimation(300, new Duration(TimeSpan.FromSeconds(2)), FillBehavior.HoldEnd);
    4:     targetButton.BeginAnimation(Button.WidthProperty, doubleAnimation);
    5: }

    just apply double animation to Width property of TargetButton(its FillBehavior is HoldEnd)

“Set Width of Target Button to 200” button(Button 2)

    1: private void SetButtonWidth(object sender, RoutedEventArgs e)
    2: {
    3:     targetButton.Width = 200;
    4: }

“Clear Animation(Copying Value)” button (Button 3)

    1: private void ClearAnimationWithCopy(object sender, RoutedEventArgs e)
    2: {
    3:     targetButton.Width = targetButton.ActualWidth;
    4:     targetButton.BeginAnimation(Button.WidthProperty, null);
    5: }

“Clear Animation” button(Button 4)

    1: private void ClearAnimation(object sender, RoutedEventArgs e)
    2: {
    3:     targetButton.BeginAnimation(Button.WidthProperty, null);
    4: }
 Then following the below steps:
 Step 1: Click button 1 (animation starts and Width increased to 300)
 Step 2: Click button 2 (No change on the Width)
 This is the problem described at the start of this post. The root cause is that
 Animation value source has higher priority than local value. So the code
  targetButton.Width = 200; 
 has change the local value. 
 But the effective value of Width comes from animation source.
 Step 3: Click button 4 (the Width changes to 200)
 After removing the animation, the effective value of Width is re-calculated.
 In this time, the local value is the source of effective value and since we has
 changed the local value of Width to 200. So the effective value of Width is 200.
 Step 4: Click button 1 again(animation starts and Width increased to 300)
 Step 5: Click button 3 (No change on the Width)
   this step needs some explanations. 
    1: targetButton.Width = targetButton.ActualWidth;
    2: targetButton.BeginAnimation(Button.WidthProperty, null);

 Before removing animation, set the Width using ActualWidth.
 so it updates the local value of Width to effective value provided by animation.
 After removing animation, the local value becomes effective value of Width.
 So no change on the Width.
 You can compare this step 5 with step 3.
 Step 6: Click button 2(change Width to 200)
  Since we remove the animation, we can change the value now.