private void AnimationItemIn(ContentPresenter contentPresenter, bool reverse = false, EventHandler onCompleted = null) { if (contentPresenter == null || VisualTreeHelper.GetChildrenCount(contentPresenter) != 1) { onCompleted?.Invoke(this, EventArgs.Empty); } else { var controls = contentPresenter.VisualDepthFirstTraversal().OfType <ButtonBase>().Reverse(); var last = controls.Count() - 1; var sineEase = new SineEase { EasingMode = EasingMode.EaseOut }; int translateFrom = 80; var i = 0; var zeroKeyTime = KeyTime.FromPercent(0.0); foreach (var uiElement in controls) { if (uiElement != null) { var deferredStart = i++ *20; var deferredEnd = deferredStart + 200.0; var deferredStartKeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(deferredStart)); var deferredEndKeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(deferredEnd)); var elementTranslateFrom = translateFrom * i; ScaleTransform scaleTransform = null; TranslateTransform translateTransform = null; var transformGroup = uiElement.RenderTransform as TransformGroup; if (transformGroup != null && transformGroup.Children.Count == 2) { scaleTransform = transformGroup.Children[0] as ScaleTransform; translateTransform = transformGroup.Children[1] as TranslateTransform; } //Ensure transform created if (translateTransform == null || scaleTransform == null) { scaleTransform = new ScaleTransform(0, 0); translateTransform = new TranslateTransform { Y = elementTranslateFrom }; uiElement.RenderTransform = transformGroup = new TransformGroup() { Children = new TransformCollection(new Transform[] { scaleTransform, translateTransform }) }; uiElement.SetCurrentValue(RenderTransformOriginProperty, new Point(.5, .5)); } //Opacity var opacityAnimation = new DoubleAnimationUsingKeyFrames(); opacityAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(0, zeroKeyTime, sineEase)); opacityAnimation.KeyFrames.Add(new EasingDoubleKeyFrame(0, deferredStartKeyTime, sineEase)); opacityAnimation.KeyFrames.Add(new EasingDoubleKeyFrame((double)uiElement.GetAnimationBaseValue(OpacityProperty), deferredEndKeyTime, sineEase)); //ScaleX var scalex = new DoubleAnimationUsingKeyFrames(); scalex.KeyFrames.Add(new EasingDoubleKeyFrame(0, zeroKeyTime, sineEase)); scalex.KeyFrames.Add(new EasingDoubleKeyFrame(0, deferredStartKeyTime, sineEase)); scalex.KeyFrames.Add(new EasingDoubleKeyFrame(1, deferredEndKeyTime, sineEase)); //ScaleY var scaley = new DoubleAnimationUsingKeyFrames(); scaley.KeyFrames.Add(new EasingDoubleKeyFrame(0, zeroKeyTime, sineEase)); scaley.KeyFrames.Add(new EasingDoubleKeyFrame(0, deferredStartKeyTime, sineEase)); scaley.KeyFrames.Add(new EasingDoubleKeyFrame(1, deferredEndKeyTime, sineEase)); //TranslateY var translatey = new DoubleAnimationUsingKeyFrames(); translatey.KeyFrames.Add(new EasingDoubleKeyFrame(elementTranslateFrom, zeroKeyTime, sineEase)); translatey.KeyFrames.Add(new EasingDoubleKeyFrame(elementTranslateFrom, deferredStartKeyTime, sineEase)); translatey.KeyFrames.Add(new EasingDoubleKeyFrame(0, deferredEndKeyTime, sineEase)); //Begin animation Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath("Opacity")); Storyboard.SetTargetProperty(scalex, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)")); Storyboard.SetTargetProperty(scaley, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)")); Storyboard.SetTargetProperty(translatey, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[1].(TranslateTransform.Y)")); Storyboard.SetTarget(opacityAnimation, uiElement); Storyboard.SetTarget(scalex, uiElement); Storyboard.SetTarget(scaley, uiElement); Storyboard.SetTarget(translatey, uiElement); //Init storyboard var storyboard = new Storyboard(); storyboard.Children.Add(opacityAnimation); storyboard.Children.Add(scalex); storyboard.Children.Add(scaley); storyboard.Children.Add(translatey); //Add handler if (i == last && onCompleted != null) { EventHandler unsubscribe = null; unsubscribe = (sender, e) => { storyboard.Completed -= unsubscribe; storyboard.Completed -= onCompleted; }; storyboard.Completed += onCompleted; storyboard.Completed += unsubscribe; } if (reverse) { storyboard.AutoReverse = true; storyboard.Begin(); storyboard.Seek(TimeSpan.FromMilliseconds(deferredEnd)); storyboard.Resume(); } else { storyboard.Begin(); } } } } }