From b29479914ae05f5be76b8e384c1d0e6f94bdb2e7 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Thu, 30 Aug 2018 16:32:53 +0800 Subject: [PATCH] new ScrollViewer control 1. add IsEnableInertia Property; 2. add IsPenetrating Property; --- HandyControl/Controls/ScrollViewer.cs | 102 ++++++++++++++++++ HandyControl/HandyControl.csproj | 2 + .../Styles/Base/ContextMenuBaseStyle.xaml | 17 +-- .../Themes/Styles/Base/ListBoxBaseStyle.xaml | 15 +-- .../Styles/Base/ScrollViewerBaseStyle.xaml | 9 +- HandyControl/Themes/Styles/ScrollViewer.xaml | 5 +- HandyControlDemo/MainWindow.xaml | 12 ++- 7 files changed, 136 insertions(+), 26 deletions(-) create mode 100644 HandyControl/Controls/ScrollViewer.cs diff --git a/HandyControl/Controls/ScrollViewer.cs b/HandyControl/Controls/ScrollViewer.cs new file mode 100644 index 00000000..142dc9c2 --- /dev/null +++ b/HandyControl/Controls/ScrollViewer.cs @@ -0,0 +1,102 @@ +using System; +using System.Windows; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; +using HandyControl.Tools; + +namespace HandyControl.Controls +{ + public class ScrollViewer : System.Windows.Controls.ScrollViewer + { + private double _totalVerticalOffset; + + private bool _isRunning; + + protected override void OnMouseWheel(MouseWheelEventArgs e) + { + if (!IsEnableInertia) + { + base.OnMouseWheel(e); + return; + } + e.Handled = true; + + if (!_isRunning) + { + _totalVerticalOffset = VerticalOffset; + CurrentVerticalOffset = VerticalOffset; + } + _totalVerticalOffset = Math.Min(Math.Max(0, _totalVerticalOffset - e.Delta), ScrollableHeight); + var animation = AnimationHelper.CreateAnimation(_totalVerticalOffset, 500); + animation.EasingFunction = new CubicEase + { + EasingMode = EasingMode.EaseOut + }; + animation.FillBehavior = FillBehavior.Stop; + animation.Completed += (s,e1)=> + { + CurrentVerticalOffset = _totalVerticalOffset; + _isRunning = false; + }; + _isRunning = true; + BeginAnimation(CurrentVerticalOffsetProperty, animation); + } + + protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) => + IsPenetrating ? null : base.HitTestCore(hitTestParameters); + + /// + /// 是否支持惯性 + /// + public static readonly DependencyProperty IsEnableInertiaProperty = DependencyProperty.Register( + "IsEnableInertia", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(default(bool))); + + /// + /// 是否支持惯性 + /// + public bool IsEnableInertia + { + get => (bool) GetValue(IsEnableInertiaProperty); + set => SetValue(IsEnableInertiaProperty, value); + } + + /// + /// 控件是否可以穿透点击 + /// + public static readonly DependencyProperty IsPenetratingProperty = DependencyProperty.Register( + "IsPenetrating", typeof(bool), typeof(ScrollViewer), new PropertyMetadata(default(bool))); + + /// + /// 控件是否可以穿透点击 + /// + public bool IsPenetrating + { + get => (bool) GetValue(IsPenetratingProperty); + set => SetValue(IsPenetratingProperty, value); + } + + /// + /// 当前垂直滚动偏移 + /// + private static readonly DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register( + "CurrentVerticalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(default(double), CurrentVerticalOffsetChangedCallback)); + + private static void CurrentVerticalOffsetChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is ScrollViewer ctl && e.NewValue is double v) + { + ctl.ScrollToVerticalOffset(v); + } + } + + /// + /// 当前垂直滚动偏移 + /// + private double CurrentVerticalOffset + { + get => (double) GetValue(CurrentVerticalOffsetProperty); + set => SetValue(CurrentVerticalOffsetProperty, value); + } + } +} \ No newline at end of file diff --git a/HandyControl/HandyControl.csproj b/HandyControl/HandyControl.csproj index 5c921ce3..ea08b677 100644 --- a/HandyControl/HandyControl.csproj +++ b/HandyControl/HandyControl.csproj @@ -29,6 +29,7 @@ TRACE prompt 4 + bin\Release\HandyControl.xml @@ -40,6 +41,7 @@ ColorPicker.xaml + InfoNumericUpDown.xaml diff --git a/HandyControl/Themes/Styles/Base/ContextMenuBaseStyle.xaml b/HandyControl/Themes/Styles/Base/ContextMenuBaseStyle.xaml index 465bd8a2..2e485e57 100644 --- a/HandyControl/Themes/Styles/Base/ContextMenuBaseStyle.xaml +++ b/HandyControl/Themes/Styles/Base/ContextMenuBaseStyle.xaml @@ -1,12 +1,13 @@  + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="clr-namespace:HandyControl.Controls"> - + @@ -131,10 +132,10 @@ - \ No newline at end of file diff --git a/HandyControl/Themes/Styles/ScrollViewer.xaml b/HandyControl/Themes/Styles/ScrollViewer.xaml index e1b66ce2..a7c4e392 100644 --- a/HandyControl/Themes/Styles/ScrollViewer.xaml +++ b/HandyControl/Themes/Styles/ScrollViewer.xaml @@ -1,11 +1,12 @@  + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:controls="clr-namespace:HandyControl.Controls"> - + \ No newline at end of file diff --git a/HandyControlDemo/MainWindow.xaml b/HandyControlDemo/MainWindow.xaml index 97c2a5c0..9415a02a 100644 --- a/HandyControlDemo/MainWindow.xaml +++ b/HandyControlDemo/MainWindow.xaml @@ -39,7 +39,7 @@ - + - + @@ -451,11 +451,13 @@ - --> + + - + \ No newline at end of file