Bubbling scroll events from a ListView to its parent

前端 未结 8 1399
深忆病人
深忆病人 2020-11-28 06:25

In my WPF application I have a ListView whose ScrollViewer.VerticalScrollBarVisibility is set to Disabled. It is contained within a

相关标签:
8条回答
  • 2020-11-28 07:15

    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.

    0 讨论(0)
  • 2020-11-28 07:18

    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

    0 讨论(0)
提交回复
热议问题