Files
Futonizer/Services/SmoothScrollHelper.cs

45 lines
1.6 KiB
C#

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace Futonizer.Services;
/// <summary>
/// Scrolls a list/grid by an amount proportional to the mouse wheel delta
/// instead of relying on WPF's default per-event line scrolling. Mouse
/// "smooth scroll" utilities send many finer-grained wheel events per
/// physical notch to animate motion; WPF's default handling treats each
/// event as a full notch regardless of its magnitude, which multiplies the
/// effective scroll speed far beyond what the user intended.
/// </summary>
public static class SmoothScrollHelper
{
private const double PixelsPerStandardNotch = 48.0;
public static void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
if (sender is not DependencyObject start) return;
var scrollViewer = FindVisualChild<ScrollViewer>(start);
if (scrollViewer == null) return;
double offsetDelta = -(e.Delta / 120.0) * PixelsPerStandardNotch;
scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offsetDelta);
e.Handled = true;
}
private static T? FindVisualChild<T>(DependencyObject parent) where T : DependencyObject
{
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is T typed) return typed;
var descendant = FindVisualChild<T>(child);
if (descendant != null) return descendant;
}
return null;
}
}