@@ -33,19 +33,42 @@ public TabControl TabControl
3333 DependencyProperty . Register ( nameof ( TabControl ) , typeof ( TabControl ) ,
3434 typeof ( TabControlHeaderScrollBehavior ) , new PropertyMetadata ( null , OnTabControlChanged ) ) ;
3535
36+
3637 private static void OnTabControlChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
3738 {
3839 var behavior = ( TabControlHeaderScrollBehavior ) d ;
3940 if ( e . OldValue is TabControl oldTabControl )
4041 {
4142 oldTabControl . SelectionChanged -= behavior . OnTabChanged ;
43+ oldTabControl . SizeChanged -= behavior . OnTabControlSizeChanged ;
4244 }
4345 if ( e . NewValue is TabControl newTabControl )
4446 {
4547 newTabControl . SelectionChanged += behavior . OnTabChanged ;
48+ newTabControl . SizeChanged += behavior . OnTabControlSizeChanged ;
4649 }
4750 }
4851
52+ public FrameworkElement ScrollableContent
53+ {
54+ get => ( FrameworkElement ) GetValue ( ScrollableContentProperty ) ;
55+ set => SetValue ( ScrollableContentProperty , value ) ;
56+ }
57+
58+ public static readonly DependencyProperty ScrollableContentProperty =
59+ DependencyProperty . Register ( nameof ( ScrollableContent ) , typeof ( FrameworkElement ) ,
60+ typeof ( TabControlHeaderScrollBehavior ) , new PropertyMetadata ( null , OnScrollableContentChanged ) ) ;
61+
62+ private static void OnScrollableContentChanged ( DependencyObject d , DependencyPropertyChangedEventArgs e )
63+ {
64+ var behavior = ( TabControlHeaderScrollBehavior ) d ;
65+ behavior . AddPaddingToScrollableContentIfWiderThanViewPort ( ) ;
66+ }
67+
68+ internal const double ScrollOffset = 40 ; // MD spec says 52 DP, but that seems a little excessive in practice
69+ internal static readonly Thickness ScrollableContentPadding = new ( ScrollOffset , 0 , ScrollOffset , 0 ) ;
70+ internal static readonly Thickness NoScrollableContentPadding = new ( 0 ) ;
71+
4972 private double ? _desiredScrollStart ;
5073 private bool _isAnimatingScroll ;
5174
@@ -70,10 +93,30 @@ bool IsMovingForward()
7093 int GetItemIndex ( object ? item ) => tabControl . Items . IndexOf ( item ) ;
7194 }
7295
96+ private void OnTabControlSizeChanged ( object sender , SizeChangedEventArgs _ ) => AddPaddingToScrollableContentIfWiderThanViewPort ( ) ;
97+ private void AssociatedObject_SizeChanged ( object sender , SizeChangedEventArgs _ ) => AddPaddingToScrollableContentIfWiderThanViewPort ( ) ;
98+
99+ private void AddPaddingToScrollableContentIfWiderThanViewPort ( )
100+ {
101+ if ( ScrollableContent is null )
102+ return ;
103+
104+ if ( ScrollableContent . ActualWidth > TabControl . ActualWidth )
105+ {
106+ ScrollableContent . Margin = ScrollableContentPadding ;
107+ }
108+ else
109+ {
110+ ScrollableContent . Margin = NoScrollableContentPadding ;
111+ }
112+ }
113+
73114 protected override void OnAttached ( )
74115 {
75116 base . OnAttached ( ) ;
76117 AssociatedObject . ScrollChanged += AssociatedObject_ScrollChanged ;
118+ AssociatedObject . SizeChanged += AssociatedObject_SizeChanged ;
119+ Dispatcher . BeginInvoke ( ( ) => AddPaddingToScrollableContentIfWiderThanViewPort ( ) ) ;
77120 }
78121
79122 protected override void OnDetaching ( )
@@ -82,6 +125,7 @@ protected override void OnDetaching()
82125 if ( AssociatedObject is { } ao )
83126 {
84127 ao . ScrollChanged -= AssociatedObject_ScrollChanged ;
128+ ao . SizeChanged -= AssociatedObject_SizeChanged ;
85129 }
86130 }
87131
0 commit comments