summaryrefslogtreecommitdiff
path: root/Gestor.Common/Gestor.Common.Helpers/ScrollAnimationBehavior.cs
blob: 6332e15709e03cad99e086ebb5ae9e6d6c5cc33e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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);
		}
	}
}