From 1f4e14b2e973ee7de337fd4866d9a5ceff5cb6d1 Mon Sep 17 00:00:00 2001 From: Lucas Faria Mendes Date: Mon, 30 Mar 2026 10:38:18 -0300 Subject: chore: location --- .../ScrollAnimationBehavior.cs | 124 +++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 Codemerx/Gestor.Common/Gestor.Common.Helpers/ScrollAnimationBehavior.cs (limited to 'Codemerx/Gestor.Common/Gestor.Common.Helpers/ScrollAnimationBehavior.cs') diff --git a/Codemerx/Gestor.Common/Gestor.Common.Helpers/ScrollAnimationBehavior.cs b/Codemerx/Gestor.Common/Gestor.Common.Helpers/ScrollAnimationBehavior.cs new file mode 100644 index 0000000..6332e15 --- /dev/null +++ b/Codemerx/Gestor.Common/Gestor.Common.Helpers/ScrollAnimationBehavior.cs @@ -0,0 +1,124 @@ +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); + } + } +} \ No newline at end of file -- cgit v1.2.3