void StartAnimation(DependencyProperty property, TimeSpan beginTime, bool isLast = false) { DoubleAnimationUsingKeyFrames d = new DoubleAnimationUsingKeyFrames(); d.KeyFrames.Add(new LinearDoubleKeyFrame(.25d, KeyTime.FromPercent(.10d))); d.KeyFrames.Add(new LinearDoubleKeyFrame(.3d, KeyTime.FromPercent(.15d))); d.KeyFrames.Add(new LinearDoubleKeyFrame(.7d, KeyTime.FromPercent(.85d))); d.KeyFrames.Add(new LinearDoubleKeyFrame(.75d, KeyTime.FromPercent(.90d))); d.KeyFrames.Add(new LinearDoubleKeyFrame(1d, KeyTime.FromPercent(1d))); d.Duration = TimeSpan.FromSeconds(3); d.BeginTime = beginTime; d.FillBehavior = FillBehavior.Stop; if (isLast) { if (this.observedAnimation != null) { this.observedAnimation.StopObserving(); } this.observedAnimation = new AnimationObserver(this, d); } this.BeginAnimation(property, null); this.BeginAnimation(property, d); }
void OnLastAnimationCompleted(AnimationObserver observer) { if (observer == this.observedAnimation) { this.observedAnimation = null; StartOrStopAnimations(); } }
/// <summary> /// Handles changes to the 'AnimationType' attached property. /// </summary> private static void OnAnimationTypePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { var frameworkElement = sender as FrameworkElement; if (frameworkElement != null) { // If AnimationType is set to True on this framework element, if (GetAnimationType(frameworkElement) != AnimationType.None) { // Add this framework element to hooked list ... AnimationObserver.MonitorElement(frameworkElement); } else { // ... otherwise, remove it from the hooked list AnimationObserver.ReleaseElement(frameworkElement); } } }
/// <summary> /// Coerce visibility. /// </summary> private static object CoerceVisibility(DependencyObject dependencyObject, object baseValue) { // Make sure the DependencyObject is a FrameworkElement var frameworkElement = dependencyObject as FrameworkElement; if (frameworkElement == null) { return(baseValue); } // Cast to type safe value var visibility = (Visibility)baseValue; // If Visibility value hasn't change, do nothing. This can happen if the Visibility property is set // using data binding and the binding source has changed but the new visibility value hasn't changed. if (visibility == frameworkElement.Visibility) { return(baseValue); } // If element is not hooked by our attached property, stop here if (AnimationObserver.IsMonitoredElement(frameworkElement) == false) { return(baseValue); } // If element has IgnoreFirstTime flag set, then ignore the first time the property is coerced. if (GetIgnoreFirstTime(frameworkElement) == true) { SetIgnoreFirstTime(frameworkElement, false); return(baseValue); } // Update animation flag. If animation already started - don't restart it (otherwise, infinite loop) if (AnimationObserver.ReverseAnimationRunningFlag(frameworkElement) == true) { return(baseValue); } // If we get here, it means we have to start fade in or fade out animation. In any case return value // of this method will be Visibility.Visible, to allow the animation. var doubleAnimation = new DoubleAnimation { Duration = new Duration(TimeSpan.FromMilliseconds(GetAnimationDuration(frameworkElement))) }; // When animation completes, set the visibility value to the requested value (baseValue) doubleAnimation.Completed += (sender, eventArgs) => { if (visibility == Visibility.Visible) { // In case we change into Visibility.Visible, the correct value is already set. // So just update the animation started flag AnimationObserver.ReverseAnimationRunningFlag(frameworkElement); } else { // This will trigger value coercion again but ReverseAnimationRunningFlag() function will // return true this time, thus animation will not be triggered. if (BindingOperations.IsDataBound(frameworkElement, UIElement.VisibilityProperty)) { // Set visiblity using bounded value var bindingValue = BindingOperations.GetBinding(frameworkElement, UIElement.VisibilityProperty); if (bindingValue == null) { return; } BindingOperations.SetBinding(frameworkElement, UIElement.VisibilityProperty, bindingValue); } else { // No binding, just assign the value frameworkElement.Visibility = visibility; } } }; doubleAnimation.To = visibility == Visibility.Visible ? 1.0 : 0.0; // Start animation frameworkElement.BeginAnimation(UIElement.OpacityProperty, doubleAnimation); // Make sure the element remains visible during the animation. The original requested value will be // set in the completed event of the animation return(Visibility.Visible); }