Bubbling scroll events from a ListView to its parent

前端 未结 8 1438
深忆病人
深忆病人 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条回答
  •  Happy的楠姐
    2020-11-28 07:08

    If you're coming here looking for a solution to bubble the event ONLY if the child is at the top and scrolling up or the bottom and scrolling down, here's a solution. I only tested this with DataGrid, but it should work with other controls as well.

    public class ScrollParentWhenAtMax : Behavior
    {
        protected override void OnAttached()
        {
            base.OnAttached();
            this.AssociatedObject.PreviewMouseWheel += PreviewMouseWheel;
        }
    
        protected override void OnDetaching()
        {
            this.AssociatedObject.PreviewMouseWheel -= PreviewMouseWheel;
            base.OnDetaching();
        }
    
        private void PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            var scrollViewer = GetVisualChild(this.AssociatedObject);
            var scrollPos = scrollViewer.ContentVerticalOffset;
            if ((scrollPos == scrollViewer.ScrollableHeight && e.Delta < 0)
                || (scrollPos == 0 && e.Delta > 0))
            {
                e.Handled = true;
                var e2 = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
                e2.RoutedEvent = UIElement.MouseWheelEvent;
                AssociatedObject.RaiseEvent(e2);
            }
        }
    
        private static T GetVisualChild(DependencyObject parent) where T : Visual
        {
            T child = default(T);
    
            int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < numVisuals; i++)
            {
                Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
                child = v as T;
                if (child == null)
                {
                    child = GetVisualChild(v);
                }
                if (child != null)
                {
                    break;
                }
            }
            return child;
        }
    }
    

    To attach this behavior, add the following XMLNS and XAML to your element:

        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    
        
            
        
    

提交回复
热议问题