/// <summary> /// Animates the values of all of the object's primitive properties /// to the values of all of the properties with the same names /// and types in the specified object. /// </summary> /// /// <param name="target"> /// the object who contains similarly named properties as the object /// whose values should be animated to. /// </param> public void AnimateTo(object target) { // If the object is immutable, it cannot be animated. if (IsImmutable()) { throw new InvalidOperationException("An immutable object cannot be animated"); } // The value being animated to needs to be the same type as the wrapped // object. var type = Object.GetType(); var targetType = target.GetType(); if (!type.IsAssignableFrom(targetType)) { throw new ArgumentException("The value being animated to must be the same type as the wrapped object"); } // Only primitive instance properties should be animated. var searchFlags = BindingFlags.Instance; var objectProperties = from property in type.GetProperties(searchFlags) where property.PropertyType.IsPrimitive select property; var lastProperty = objectProperties.Last(); foreach (var property in objectProperties) { var startValue = (double)property.GetValue(Object); var endValue = (double)property.GetValue(target); var propertyAnimation = new ValueAnimation(startValue, endValue, DefaultDuration, DefaultInterpolator); propertyAnimation.AnimationIncremented += (_, __) => property.SetValue(Object, propertyAnimation.CurrentValue); this.AddAnimation(propertyAnimation); // Once the last property is incremented, the ObjectChanged event should be triggered. if (property.Equals(lastProperty)) { propertyAnimation.AnimationIncremented += (_, __) => { if (ObjectChanged != null) { ObjectChanged(this); } } } ; propertyAnimation.Start(); } }
/// <summary> /// Starts the specified animation. /// </summary> /// /// <param name="animation"> /// the animation to be started. /// </param> private void StartAnimation(ValueAnimation animation) { // Ensure the value is not already being animated. if (Animations.Length > 1) { // Remove the animation, since only one animation can run at a time. RemoveAnimation(animation, new AnimationEventArgs(animation)); return; } // Update the value at every animation frame. animation.AnimationIncremented += (_, __) => Value = animation.CurrentValue; // Start the animation. animation.Start(); }