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