45 lines
1.6 KiB
C#
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;
|
|
}
|
|
}
|