XFEstudio/MyFirstRespo / XFEToolBox/Views/Controls/SmoothScrollViewer.cs

using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Animation;
using XFEToolBox.Views.Behavior;

namespace XFEToolBox.Views.Controls;

public class SmoothScrollViewer : ScrollViewer
{
    public long AnimateMilliseconds { get; set; } = 300;
    public double ScrollDistanceMultiplier { get; set; } = 1;
    private double lastLocation = 0;
    protected override void OnMouseWheel(MouseWheelEventArgs e)
    {
        double wheelChange = e.Delta;
        double newOffset = lastLocation - wheelChange * ScrollDistanceMultiplier;
        ScrollToVerticalOffset(lastLocation);
        if (newOffset < 0)
            newOffset = 0;
        if (newOffset > ScrollableHeight)
            newOffset = ScrollableHeight;
        AnimateScroll(newOffset);
        lastLocation = newOffset;
        e.Handled = true;
    }
    private void AnimateScroll(double toValue)
    {
        BeginAnimation(ScrollViewerBehavior.VerticalOffsetProperty, null);
        var animation = new DoubleAnimation
        {
            EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut },
            From = VerticalOffset,
            To = toValue,
            Duration = TimeSpan.FromMilliseconds(AnimateMilliseconds)
        };
        BeginAnimation(ScrollViewerBehavior.VerticalOffsetProperty, animation);
    }
}