private void AnimatePropertyChange()

in src/Microsoft.Xaml.Behaviors/Core/ChangePropertyAction.cs [194:248]


        private void AnimatePropertyChange(PropertyInfo propertyInfo, object fromValue, object newValue)
        {
            Storyboard sb = new Storyboard();
            Timeline timeline;
            if (typeof(double).IsAssignableFrom(propertyInfo.PropertyType))
            {
                timeline = this.CreateDoubleAnimation((double)fromValue, (double)newValue);
            }
            else if (typeof(Color).IsAssignableFrom(propertyInfo.PropertyType))
            {
                timeline = this.CreateColorAnimation((Color)fromValue, (Color)newValue);
            }
            else if (typeof(Point).IsAssignableFrom(propertyInfo.PropertyType))
            {
                timeline = this.CreatePointAnimation((Point)fromValue, (Point)newValue);
            }
            else
            {
                timeline = this.CreateKeyFrameAnimation(fromValue, newValue);
            }

            timeline.Duration = this.Duration;
            sb.Children.Add(timeline);

            if (this.TargetObject == null &&
                this.TargetName != null &&
                this.Target is Freezable)
            {
                // Workaround Dev10 bug 542374, Storyboard.Target property does not work properly
                // when the target of the animation is a freezable.
                Storyboard.SetTargetName(sb, this.TargetName);
            }
            else
            {
                Storyboard.SetTarget(sb, (DependencyObject)this.Target);
            }
            Storyboard.SetTargetProperty(sb, new PropertyPath(propertyInfo.Name));

            sb.Completed += (o, e) =>
            {
                propertyInfo.SetValue(this.Target, newValue, new object[0]);
            };
            sb.FillBehavior = FillBehavior.Stop;

            // Give the storyboard the neccesary context to resolve target names
            FrameworkElement containingObject = this.AssociatedObject as FrameworkElement;
            if (containingObject != null)
            {
                sb.Begin(containingObject);
            }
            else
            {
                sb.Begin();
            }
        }