private void logItemsScroll_ScrollChanged(object sender, ScrollChangedEventArgs args) { bool cond = logItemsScroll.VerticalOffset >= logItemsScroll.ScrollableHeight - 50; // e.VerticalChange can actually be 0, so test for positive and negative values explicitly if (args.VerticalChange > 0) { // Scrolled down, can only set flag if in range logItemsScrolledNearEnd |= cond; } else if (args.VerticalChange < 0) { // Scrolled up, can only clear flag if out of range logItemsScrolledNearEnd &= cond; // Stop the scroll animation immediately when scrolling up if (DependencyPropertyHelper.GetValueSource(logItemsScrollMediator, ScrollViewerOffsetMediator.VerticalOffsetProperty).IsAnimated) { if (logItemsScrollMediator != null) // Should always be true here { logItemsScrollMediator.StopDoubleAnimation(ScrollViewerOffsetMediator.VerticalOffsetProperty); logItemsScrollPixelDc.Fire(); } } } }
public void AnimateStatusText(string newText) { int durationMs = 300; TimeSpan duration = TimeSpan.FromMilliseconds(durationMs); double offset = Math.Max(15, StatusText.ActualHeight); // Prepare animation if (statusTextAnimationDc != null) { statusTextAnimationDc.Fire(); } StatusTextShadow.Text = newText; // Animate both text blocks AnimationHelper.AnimateEaseOut(StatusTextTranslateTransform, TranslateTransform.YProperty, 0, -offset, duration); AnimationHelper.AnimateEaseOut(StatusText, TextBlock.OpacityProperty, 1, 0, duration); AnimationHelper.AnimateEaseOut(StatusTextShadowTranslateTransform, TranslateTransform.YProperty, offset, 0, duration); AnimationHelper.AnimateEaseOut(StatusTextShadow, TextBlock.OpacityProperty, 0, 1, duration); // Finish up animation statusTextAnimationDc = DelayedCall.Start(StatusTextAnimationFinished, durationMs); }