Skip to content

Commit 0511117

Browse files
Adding smooth/animated scrolling to the behavior
1 parent 8f02def commit 0511117

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

src/MaterialDesignThemes.Wpf/Behaviors/Internal/TabControlHeaderScrollBehavior.cs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
using System.Diagnostics;
2+
using System.Windows.Media.Animation;
23
using Microsoft.Xaml.Behaviors;
34

45
namespace MaterialDesignThemes.Wpf.Behaviors.Internal;
56

67
public class TabControlHeaderScrollBehavior : Behavior<ScrollViewer>
78
{
9+
public static readonly DependencyProperty CustomHorizontalOffsetProperty =
10+
DependencyProperty.RegisterAttached("CustomHorizontalOffset", typeof(double),
11+
typeof(TabControlHeaderScrollBehavior), new PropertyMetadata(0d, CustomHorizontalOffsetChanged));
12+
public static double GetCustomHorizontalOffset(DependencyObject obj) => (double)obj.GetValue(CustomHorizontalOffsetProperty);
13+
public static void SetCustomHorizontalOffset(DependencyObject obj, double value) => obj.SetValue(CustomHorizontalOffsetProperty, value);
14+
private static void CustomHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
15+
{
16+
var scrollViewer = (ScrollViewer)d;
17+
scrollViewer.ScrollToHorizontalOffset((double)e.NewValue);
18+
}
19+
820
public static readonly DependencyProperty TabScrollDirectionProperty =
9-
DependencyProperty.RegisterAttached("TabScrollDirection", typeof(TabScrollDirection), typeof(TabControlHeaderScrollBehavior), new PropertyMetadata(TabScrollDirection.Unknown));
21+
DependencyProperty.RegisterAttached("TabScrollDirection", typeof(TabScrollDirection),
22+
typeof(TabControlHeaderScrollBehavior), new PropertyMetadata(TabScrollDirection.Unknown));
1023
public static TabScrollDirection GetTabScrollDirection(DependencyObject obj) => (TabScrollDirection)obj.GetValue(TabScrollDirectionProperty);
1124
public static void SetTabScrollDirection(DependencyObject obj, TabScrollDirection value) => obj.SetValue(TabScrollDirectionProperty, value);
1225

@@ -33,12 +46,16 @@ private static void OnTabControlChanged(DependencyObject d, DependencyPropertyCh
3346
}
3447
}
3548

49+
private double? _desiredScrollStart;
50+
private bool _isAnimatingScroll;
51+
3652
private void OnTabChanged(object sender, SelectionChangedEventArgs e)
3753
{
3854
TabControl tabControl = (TabControl)sender;
3955

4056
if (e.AddedItems.Count > 0)
4157
{
58+
_desiredScrollStart = AssociatedObject.ContentHorizontalOffset;
4259
SetTabScrollDirection(tabControl, (IsMovingForward() ? TabScrollDirection.Forward : TabScrollDirection.Backward));
4360
}
4461

@@ -70,7 +87,23 @@ protected override void OnDetaching()
7087

7188
private void AssociatedObject_ScrollChanged(object sender, ScrollChangedEventArgs e)
7289
{
73-
Debug.WriteLine($"HorizontalOffset: {e.HorizontalOffset}, ViewportWidth: {e.ViewportWidth}, ExtentWidth: {e.ExtentWidth}");
90+
Debug.WriteLine($"ContentHorizontalOffset: {AssociatedObject.ContentHorizontalOffset}, HorizontalOffset: {e.HorizontalOffset}, HorizontalChange: {e.HorizontalChange}, ViewportWidth: {e.ViewportWidth}, ExtentWidth: {e.ExtentWidth}");
91+
if (_isAnimatingScroll || _desiredScrollStart is not { } desiredOffsetStart) return;
92+
93+
double originalValue = desiredOffsetStart;
94+
double newValue = e.HorizontalOffset;
95+
96+
_isAnimatingScroll = true;
97+
AssociatedObject.ScrollToHorizontalOffset(originalValue);
98+
Debug.WriteLine($"Initiating animated scroll from {originalValue} to {newValue}. Change is: {e.HorizontalChange}");
99+
DoubleAnimation scrollAnimation = new(originalValue, newValue, new Duration(TimeSpan.FromMilliseconds(250)));
100+
scrollAnimation.Completed += (_, _) =>
101+
{
102+
Debug.WriteLine("Animation completed");
103+
_desiredScrollStart = null;
104+
_isAnimatingScroll = false;
105+
};
106+
AssociatedObject.BeginAnimation(TabControlHeaderScrollBehavior.CustomHorizontalOffsetProperty, scrollAnimation);
74107
}
75108
}
76109

0 commit comments

Comments
 (0)