diff --git a/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs b/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs index 8fc34154..39cb98da 100644 --- a/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs +++ b/src/Shared/HandyControl_Shared/Controls/Other/ScrollViewer.cs @@ -17,6 +17,8 @@ namespace HandyControl.Controls private bool _isRunning; + private Storyboard _scrollingAnimation = new Storyboard(); + /// /// 滚动方向 /// @@ -28,7 +30,7 @@ namespace HandyControl.Controls /// public Orientation Orientation { - get => (Orientation) GetValue(OrientationProperty); + get => (Orientation)GetValue(OrientationProperty); set => SetValue(OrientationProperty, value); } @@ -43,7 +45,7 @@ namespace HandyControl.Controls /// public bool CanMouseWheel { - get => (bool) GetValue(CanMouseWheelProperty); + get => (bool)GetValue(CanMouseWheelProperty); set => SetValue(CanMouseWheelProperty, value); } @@ -101,7 +103,7 @@ namespace HandyControl.Controls } internal void ScrollToVerticalOffsetInternal(double offset, double milliseconds = 500) - { + { var animation = AnimationHelper.CreateAnimation(offset, milliseconds); animation.EasingFunction = new CubicEase { @@ -114,7 +116,11 @@ namespace HandyControl.Controls _isRunning = false; }; _isRunning = true; - BeginAnimation(CurrentVerticalOffsetProperty, animation); + + _scrollingAnimation.Children.Add(animation); + BeginStoryboard(_scrollingAnimation); + + //BeginAnimation(CurrentVerticalOffsetProperty, animation); } internal void ScrollToHorizontalOffsetInternal(double offset, double milliseconds = 500) @@ -131,7 +137,8 @@ namespace HandyControl.Controls _isRunning = false; }; _isRunning = true; - BeginAnimation(CurrentHorizontalOffsetProperty, animation); + + BeginAnimation(CurrentHorizontalOffsetProperty, animation, HandoffBehavior.Compose); } protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) => @@ -150,7 +157,7 @@ namespace HandyControl.Controls public static bool GetIsEnableInertia(DependencyObject element) { - return (bool) element.GetValue(IsEnableInertiaProperty); + return (bool)element.GetValue(IsEnableInertiaProperty); } /// @@ -184,7 +191,7 @@ namespace HandyControl.Controls public static bool GetIsPenetrating(DependencyObject element) { - return (bool) element.GetValue(IsPenetratingProperty); + return (bool)element.GetValue(IsPenetratingProperty); } /// @@ -207,7 +214,7 @@ namespace HandyControl.Controls private double CurrentVerticalOffset { // ReSharper disable once UnusedMember.Local - get => (double) GetValue(CurrentVerticalOffsetProperty); + get => (double)GetValue(CurrentVerticalOffsetProperty); set => SetValue(CurrentVerticalOffsetProperty, value); } @@ -230,7 +237,7 @@ namespace HandyControl.Controls /// public double CurrentHorizontalOffset { - get => (double) GetValue(CurrentHorizontalOffsetProperty); + get => (double)GetValue(CurrentHorizontalOffsetProperty); set => SetValue(CurrentHorizontalOffsetProperty, value); } } diff --git a/src/Shared/HandyControl_Shared/Controls/TabControl/TabControl.cs b/src/Shared/HandyControl_Shared/Controls/TabControl/TabControl.cs index 6967947d..15e347d9 100644 --- a/src/Shared/HandyControl_Shared/Controls/TabControl/TabControl.cs +++ b/src/Shared/HandyControl_Shared/Controls/TabControl/TabControl.cs @@ -10,16 +10,31 @@ namespace HandyControl.Controls { [TemplatePart(Name = OverflowButtonKey, Type = typeof(ContextMenuToggleButton))] [TemplatePart(Name = HeaderPanelKey, Type = typeof(TabPanel))] + [TemplatePart(Name = OverflowScrollviewer, Type = typeof(ScrollViewer))] + [TemplatePart(Name = OverflowButtonLeft, Type = typeof(Button))] + [TemplatePart(Name = OverflowButtonRight, Type = typeof(Button))] public class TabControl : System.Windows.Controls.TabControl { private const string OverflowButtonKey = "PART_OverflowButton"; private const string HeaderPanelKey = "PART_HeaderPanel"; + private const string OverflowScrollviewer = "PART_OverflowScrollviewer"; + + private const string OverflowButtonLeft = "PART_OverflowButtonLeft"; + + private const string OverflowButtonRight = "PART_OverflowButtonRight"; + private ContextMenuToggleButton _buttonOverflow; private TabPanel _headerPanel; + private ScrollViewer _scrollviewerOverflow; + + private Button _buttonOverflowLeft; + + private Button _buttonOverflowRight; + /// /// 是否为内部操作 /// @@ -115,6 +130,16 @@ namespace HandyControl.Controls set => SetValue(TabItemHeightProperty, value); } + //TODO: Implement this + public bool IsScrollable + { + get { return (bool)GetValue(IsScrollableProperty); } + set { SetValue(IsScrollableProperty, value); } + } + + public static readonly DependencyProperty IsScrollableProperty = + DependencyProperty.Register("IsScrollable", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.FalseBox)); + /// /// 可见的标签数量 /// @@ -133,7 +158,7 @@ namespace HandyControl.Controls if (!IsEnableTabFill) { _itemShowCount = (int)(ActualWidth / TabItemWidth); - _buttonOverflow.Show(Items.Count > 0 && Items.Count >= _itemShowCount); + _buttonOverflow.Show(Items.Count > 0 && Items.Count >= _itemShowCount); } if (IsInternalAction) @@ -169,6 +194,33 @@ namespace HandyControl.Controls if (IsEnableTabFill) return; _buttonOverflow = Template.FindName(OverflowButtonKey, this) as ContextMenuToggleButton; + _scrollviewerOverflow = Template.FindName(OverflowScrollviewer, this) as ScrollViewer; + _buttonOverflowLeft = Template.FindName(OverflowButtonLeft, this) as Button; + _buttonOverflowRight = Template.FindName(OverflowButtonRight, this) as Button; + + _buttonOverflowLeft.Click += (s, e) => + { + var currentOffset = _scrollviewerOverflow.CurrentHorizontalOffset; + var modulo = (currentOffset % TabItemWidth); + var offset = currentOffset - (modulo == 0 ? TabItemWidth : modulo); + + if (offset >= 0) + { + _scrollviewerOverflow.ScrollToHorizontalOffsetInternal(offset); + } + }; + + _buttonOverflowRight.Click += (s, e) => + { + var currentOffset = _scrollviewerOverflow.CurrentHorizontalOffset; + var offset = currentOffset + (TabItemWidth - (currentOffset % TabItemWidth)); + + if(offset <= _scrollviewerOverflow.ScrollableWidth) + { + _scrollviewerOverflow.ScrollToHorizontalOffsetInternal(offset); + } + }; + if (_buttonOverflow != null) { _itemShowCount = (int)(ActualWidth / TabItemWidth); diff --git a/src/Shared/HandyControl_Shared/Themes/Styles/TabControl.xaml b/src/Shared/HandyControl_Shared/Themes/Styles/TabControl.xaml index 870ab401..583d6614 100644 --- a/src/Shared/HandyControl_Shared/Themes/Styles/TabControl.xaml +++ b/src/Shared/HandyControl_Shared/Themes/Styles/TabControl.xaml @@ -91,23 +91,78 @@ - - - - - - - - - - + + + + + + + + + + + + + + +