Skip to content

Instantly share code, notes, and snippets.

@emoacht
Created April 15, 2023 02:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emoacht/b7310343375e3408adf88da52de17b7f to your computer and use it in GitHub Desktop.
Save emoacht/b7310343375e3408adf88da52de17b7f to your computer and use it in GitHub Desktop.
Scroll ScrollViewer of ListBox by mouse wheel.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Windows;
using System.Windows.Media;
public static class DependencyObjectExtensions
{
public static bool TryFindDescendant<T>(this DependencyObject reference, [NotNullWhen(true)] out T? descendant) where T : DependencyObject
{
var queue = new Queue<DependencyObject>();
var parent = reference;
while (parent is not null)
{
int count = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
if (child is T buffer)
{
descendant = buffer;
return true;
}
queue.Enqueue(child);
}
parent = (0 < queue.Count) ? queue.Dequeue() : null;
}
descendant = default;
return false;
}
}
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
internal static class ListBoxHelper
{
public static int GetHorizontalScrollDivider(DependencyObject obj)
{
return (int)obj.GetValue(HorizontalScrollDividerProperty);
}
public static void SetHorizontalScrollDivider(DependencyObject obj, int value)
{
obj.SetValue(HorizontalScrollDividerProperty, value);
}
public static readonly DependencyProperty HorizontalScrollDividerProperty =
DependencyProperty.RegisterAttached(
"HorizontalScrollDivider",
typeof(int),
typeof(ListBoxHelper),
new PropertyMetadata(
defaultValue: 0,
propertyChangedCallback: (d, e) =>
{
if (d is not ListBox listBox)
return;
switch ((int)e.OldValue, (int)e.NewValue)
{
case (0, not 0):
listBox.PreviewMouseWheel += OnPreviewMouseWheel;
break;
case (_, 0):
listBox.PreviewMouseWheel -= OnPreviewMouseWheel;
break;
}
}));
private static void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
var listBox = (ListBox)sender;
if (!listBox.TryFindDescendant(out ScrollViewer? viewer))
return;
int divider = GetHorizontalScrollDivider(listBox);
double offset = viewer.HorizontalOffset;
offset += e.Delta / (double)divider;
viewer.ScrollToHorizontalOffset(offset);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment