private void UpdateBusyAnimation() { if ((BusyAnimation == null || (BusyAnimation != null && BusyAnimation.Name == DefaultBusyAnimationName)) && Track != null && _busyBar != null) { if (BusyAnimation != null && IsBusyAnimationRunning) { IsBusyAnimationRunning = false; BusyAnimation.Stop(this); BusyAnimation.Remove(this); } // NOTE: Lack of contracts: Children always have collection instance Contract.Assume(_busyBar.Children != null); BusyAnimation = new Storyboard { Name = DefaultBusyAnimationName, RepeatBehavior = RepeatBehavior.Forever }; var firstCycleAnimations = new Collection <DoubleAnimation>(); var secondCycleAnimations = new Collection <DoubleAnimation>(); const double time = 0.25; const double durationTime = time * 2; const double beginTimeIncrement = time / 2; const double shortPauseTime = time; const double longPauseTime = time * 1.5; var partMotionTime = (_busyBar.Children.Count - 1) * beginTimeIncrement + durationTime + shortPauseTime; var length = Math.Min(Track.ActualWidth, Track.ActualHeight) * Math.PI; for (var i = 0; i < _busyBar.Children.Count; i++) { var element = (FrameworkElement)_busyBar.Children[_busyBar.Children.Count - i - 1]; if (element != null) { var elementLength = Math.Max(element.Width, element.Height); var index = (_busyBar.Children.Count - 1) / 2 - i; var endPosition = length / 2 + index * (elementLength * 2); var endAngle = endPosition / length * 360d; var duration = new Duration(TimeSpan.FromSeconds(durationTime)); var firstCycleAnimation = new DoubleAnimation(0d, endAngle, duration) { BeginTime = TimeSpan.FromSeconds(i * beginTimeIncrement) }; Storyboard.SetTarget(firstCycleAnimation, element); Storyboard.SetTargetProperty(firstCycleAnimation, new PropertyPath(AngleProperty)); var secondCycleAnimation = new DoubleAnimation(0d, endAngle, duration) { BeginTime = TimeSpan.FromSeconds(partMotionTime + durationTime + i * beginTimeIncrement) }; Storyboard.SetTarget(secondCycleAnimation, element); Storyboard.SetTargetProperty(secondCycleAnimation, new PropertyPath(AngleProperty)); firstCycleAnimations.Add(firstCycleAnimation); secondCycleAnimations.Add(secondCycleAnimation); } } for (var i = 0; i < _busyBar.Children.Count; i++) { var element = (FrameworkElement)_busyBar.Children[_busyBar.Children.Count - i - 1]; if (element != null) { var duration = new Duration(TimeSpan.FromSeconds(durationTime)); var firstCycleAnimation = new DoubleAnimation(360d, duration) { BeginTime = TimeSpan.FromSeconds(partMotionTime + i * beginTimeIncrement) }; Storyboard.SetTarget(firstCycleAnimation, element); Storyboard.SetTargetProperty(firstCycleAnimation, new PropertyPath(AngleProperty)); var secondCycleAnimation = new DoubleAnimation(360d, duration) { BeginTime = TimeSpan.FromSeconds(partMotionTime * 2 + durationTime + i * beginTimeIncrement) }; Storyboard.SetTarget(secondCycleAnimation, element); Storyboard.SetTargetProperty(secondCycleAnimation, new PropertyPath(AngleProperty)); var moveAnimation = new DoubleAnimation(-1.0, new Duration(TimeSpan.FromSeconds(0))) { BeginTime = TimeSpan.FromSeconds(partMotionTime * 2 + durationTime * 2 + i * beginTimeIncrement) }; Storyboard.SetTarget(moveAnimation, element); Storyboard.SetTargetProperty(moveAnimation, new PropertyPath(AngleProperty)); firstCycleAnimations.Add(firstCycleAnimation); secondCycleAnimations.Add(secondCycleAnimation); secondCycleAnimations.Add(moveAnimation); } } BusyAnimation.Duration = new Duration(TimeSpan.FromSeconds(longPauseTime + partMotionTime * 3 + shortPauseTime * 2 + durationTime)); // NOTE: Lack of contracts: Children always have collection instance Contract.Assume(BusyAnimation.Children != null); foreach (var animation in firstCycleAnimations) { BusyAnimation.Children.Add(animation); } foreach (var animation in secondCycleAnimations) { BusyAnimation.Children.Add(animation); } if (BusyAnimation.CanFreeze) { BusyAnimation.Freeze(); } if (State == ProgressState.Busy && IsEnabled) { BusyAnimation.Begin(this, Template, true); IsBusyAnimationRunning = true; } } }
private void UpdateBusyAnimation() { if ((BusyAnimation == null || (BusyAnimation != null && BusyAnimation.Name == DefaultBusyAnimationName)) && Track != null && _busyBar != null) { if (BusyAnimation != null && IsBusyAnimationRunning) { IsBusyAnimationRunning = false; BusyAnimation.Stop(this); BusyAnimation.Remove(this); } // NOTE: Lack of contracts: Children always have collection instance Contract.Assume(_busyBar.Children != null); BusyAnimation = new Storyboard { Name = DefaultBusyAnimationName, RepeatBehavior = RepeatBehavior.Forever }; const double time = 0.25; const double durationTime = time * 2; const double beginTimeIncrement = time / 2; const double shortPauseTime = time; const double longPauseTime = time * 1.5; var partMotionTime = (_busyBar.Children.Count - 1) * beginTimeIncrement + durationTime; var busyAnimations = new Collection <DoubleAnimation>(); var width = Track.ActualWidth; var height = Track.ActualHeight; for (var i = 0; i < _busyBar.Children.Count; i++) { var element = (FrameworkElement)_busyBar.Children[_busyBar.Children.Count - i - 1]; if (element != null) { var elementWidth = element.Width; var elementHeight = element.Height; var index = (_busyBar.Children.Count - 1) / 2 - i; var center = (Orientation == Orientation.Horizontal ? width : height) / 2; var margin = Orientation == Orientation.Horizontal ? elementWidth : elementHeight; var startPosition = -(Orientation == Orientation.Horizontal ? elementWidth : elementHeight) - 1; var endPosition = center + index * ((Orientation == Orientation.Horizontal ? elementWidth : elementHeight) + margin); var duration = new Duration(TimeSpan.FromSeconds(durationTime)); var animation = new DoubleAnimation(startPosition, endPosition, duration) { BeginTime = TimeSpan.FromSeconds(i * beginTimeIncrement) }; Storyboard.SetTarget(animation, element); Storyboard.SetTargetProperty(animation, new PropertyPath(Orientation == Orientation.Horizontal ? Canvas.LeftProperty : Canvas.TopProperty)); busyAnimations.Add(animation); } } for (var i = 0; i < _busyBar.Children.Count; i++) { var element = (FrameworkElement)_busyBar.Children[_busyBar.Children.Count - i - 1]; if (element != null) { var elementWidth = element.Width; var elementHeight = element.Height; var endPosition = (Orientation == Orientation.Horizontal ? width : height) + (Orientation == Orientation.Horizontal ? elementWidth : elementHeight) + 1; var duration = new Duration(TimeSpan.FromSeconds(durationTime)); var animation = new DoubleAnimation(endPosition, duration) { BeginTime = TimeSpan.FromSeconds(partMotionTime + shortPauseTime + i * beginTimeIncrement) }; Storyboard.SetTarget(animation, element); Storyboard.SetTargetProperty(animation, new PropertyPath(Orientation == Orientation.Horizontal ? Canvas.LeftProperty : Canvas.TopProperty)); busyAnimations.Add(animation); } } BusyAnimation.Duration = new Duration(TimeSpan.FromSeconds(partMotionTime * 2 + shortPauseTime + longPauseTime)); // NOTE: Lack of contracts: Children always have collection instance Contract.Assume(BusyAnimation.Children != null); foreach (var animation in busyAnimations) { BusyAnimation.Children.Add(animation); } if (BusyAnimation.CanFreeze) { BusyAnimation.Freeze(); } if (State == ProgressState.Busy && IsEnabled) { BusyAnimation.Begin(this, Template, true); IsBusyAnimationRunning = true; } } }