In my WPF application I have a ListView
whose ScrollViewer.VerticalScrollBarVisibility
is set to Disabled
. It is contained within a
You need to capture the preview mouse wheel event in the inner listview
MyListView.PreviewMouseWheel += HandlePreviewMouseWheel;
Or in the XAML
<ListView ... PreviewMouseWheel="HandlePreviewMouseWheel">
then stop the event from scrolling the listview and raise the event in the parent listview.
private void HandlePreviewMouseWheel(object sender, MouseWheelEventArgs e) {
if (!e.Handled) {
e.Handled = true;
var eventArg = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
eventArg.RoutedEvent = UIElement.MouseWheelEvent;
eventArg.Source = sender;
var parent = ((Control)sender).Parent as UIElement;
parent.RaiseEvent(eventArg);
}
}
Creds go to @robert-wagner who solved this for me a few months ago.
Another nice solution using attached behavior. I like it because it decoples the solution from the Control.
Create a no scroling behavior which will catch the PreviewMouseWheel(Tunneling) event and raise a new MouseWheelEvent(Bubbling)
public sealed class IgnoreMouseWheelBehavior : Behavior<UIElement>
{
protected override void OnAttached( )
{
base.OnAttached( );
AssociatedObject.PreviewMouseWheel += AssociatedObject_PreviewMouseWheel ;
}
protected override void OnDetaching( )
{
AssociatedObject.PreviewMouseWheel -= AssociatedObject_PreviewMouseWheel;
base.OnDetaching( );
}
void AssociatedObject_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
e.Handled = true;
var e2 = new MouseWheelEventArgs(e.MouseDevice,e.Timestamp,e.Delta);
e2.RoutedEvent = UIElement.MouseWheelEvent;
AssociatedObject.RaiseEvent(e2);
}
}
Then attach the behavior to any UIElement with nested ScrollViewers case
<ListBox Name="ForwardScrolling">
<i:Interaction.Behaviors>
<local:IgnoreMouseWheelBehavior />
</i:Interaction.Behaviors>
</ListBox>
all credit to Josh Einstein Blog