Created
April 15, 2023 02:30
-
-
Save emoacht/b7310343375e3408adf88da52de17b7f to your computer and use it in GitHub Desktop.
Scroll ScrollViewer of ListBox by mouse wheel.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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