using System; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media.Animation; namespace Gestor.Common.Helpers { public static class ScrollAnimationBehavior { public static DependencyProperty VerticalOffsetProperty; public static DependencyProperty TimeDurationProperty; public static DependencyProperty PointsToScrollProperty; public static DependencyProperty IsEnabledProperty; private static double _currentToValue; private static Storyboard _storyboard; static ScrollAnimationBehavior() { ScrollAnimationBehavior.VerticalOffsetProperty = DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ScrollAnimationBehavior), new UIPropertyMetadata((object)0, new PropertyChangedCallback(ScrollAnimationBehavior.OnVerticalOffsetChanged))); ScrollAnimationBehavior.TimeDurationProperty = DependencyProperty.RegisterAttached("TimeDuration", typeof(TimeSpan), typeof(ScrollAnimationBehavior), new PropertyMetadata((object)(new TimeSpan(0, 0, 0, 0, 0)))); ScrollAnimationBehavior.PointsToScrollProperty = DependencyProperty.RegisterAttached("PointsToScroll", typeof(double), typeof(ScrollAnimationBehavior), new PropertyMetadata((object)0)); ScrollAnimationBehavior.IsEnabledProperty = DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(ScrollAnimationBehavior), new UIPropertyMetadata(false, new PropertyChangedCallback(ScrollAnimationBehavior.OnIsEnabledChanged))); } private static void AnimateScroll(ScrollViewer scrollViewer) { DoubleAnimationUsingKeyFrames doubleAnimationUsingKeyFrame = new DoubleAnimationUsingKeyFrames() { Duration = new Duration(ScrollAnimationBehavior.GetTimeDuration(scrollViewer)) }; doubleAnimationUsingKeyFrame.KeyFrames.Add(new EasingDoubleKeyFrame(scrollViewer.VerticalOffset, KeyTime.FromPercent(0))); doubleAnimationUsingKeyFrame.KeyFrames.Add(new EasingDoubleKeyFrame(ScrollAnimationBehavior._currentToValue, KeyTime.FromPercent(1), new SineEase() { EasingMode = EasingMode.EaseOut })); ScrollAnimationBehavior._storyboard = new Storyboard(); ScrollAnimationBehavior._storyboard.Children.Add(doubleAnimationUsingKeyFrame); Storyboard.SetTarget(doubleAnimationUsingKeyFrame, scrollViewer); Storyboard.SetTargetProperty(doubleAnimationUsingKeyFrame, new PropertyPath(ScrollAnimationBehavior.VerticalOffsetProperty)); ScrollAnimationBehavior._storyboard.Begin(); } public static TimeSpan GetTimeDuration(FrameworkElement target) { return (TimeSpan)target.GetValue(ScrollAnimationBehavior.TimeDurationProperty); } private static void OnIsEnabledChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { ScrollViewer scrollViewer = sender as ScrollViewer; if (scrollViewer != null) { scrollViewer.Loaded += new RoutedEventHandler(ScrollAnimationBehavior.ScrollerLoaded); } } private static void OnVerticalOffsetChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) { ScrollViewer scrollViewer = target as ScrollViewer; if (scrollViewer != null) { scrollViewer.ScrollToVerticalOffset((double)e.NewValue); } } private static void ScrollerLoaded(object sender, RoutedEventArgs e) { ScrollAnimationBehavior.SetEventHandlersForScrollViewer(sender as ScrollViewer); } private static void ScrollViewerPreviewMouseWheel(object sender, MouseWheelEventArgs e) { double num; double num1 = ScrollAnimationBehavior._currentToValue; double delta = (double)e.Delta; ScrollViewer scrollViewer = (ScrollViewer)sender; double num2 = delta * 2 / 3; if (ScrollAnimationBehavior._storyboard == null || ScrollAnimationBehavior._storyboard.GetCurrentState() == ClockState.Filling) { ScrollAnimationBehavior._currentToValue = scrollViewer.VerticalOffset; } if (num2 > ScrollAnimationBehavior._currentToValue) { num = 0; } else { num = (ScrollAnimationBehavior._currentToValue - num2 > scrollViewer.ScrollableHeight ? scrollViewer.ScrollableHeight : ScrollAnimationBehavior._currentToValue - num2); } ScrollAnimationBehavior._currentToValue = num; if (ScrollAnimationBehavior._currentToValue != scrollViewer.VerticalOffset && ScrollAnimationBehavior._currentToValue != num1) { ScrollAnimationBehavior.AnimateScroll(scrollViewer); } e.Handled = true; } private static void SetEventHandlersForScrollViewer(ScrollViewer scroller) { scroller.PreviewMouseWheel += new MouseWheelEventHandler(ScrollAnimationBehavior.ScrollViewerPreviewMouseWheel); } public static void SetIsEnabled(FrameworkElement target, bool value) { target.SetValue(ScrollAnimationBehavior.IsEnabledProperty, value); } public static void SetPointsToScroll(FrameworkElement target, double value) { target.SetValue(ScrollAnimationBehavior.PointsToScrollProperty, value); } public static void SetTimeDuration(FrameworkElement target, TimeSpan value) { target.SetValue(ScrollAnimationBehavior.TimeDurationProperty, value); } } }