WPF scrolls parent container through child container

I am having some problems trying to figure out how to scroll the contents of a grid that is contained inside a scroll viewer. When trying to scroll with the mouse wheel or pan (with touch), the grid scrolls fine if the mouse / touch point is over an empty area, but if it is above certain controls (such as a group box) it scrolls. Is there some property I am overlooking to allow child panes to allow them to scroll to parent containers?

EDIT: I have misread my original layout. Here's a simplified version of my senario:

<Grid>
    <ScrollViewer Name="MainScrollViewer">
        <StackPanel>
            <ListBox />    <--Doesn't Scroll-->
            <Button />     <--Scrolls Fine-->
            <TextBlock />  <--Scrolls Fine-->
            <TextBox />    <--Scrolls Fine-->
            <DataGrid />   <--Doesn't Scroll-->
        </StackPanel>
    </ScrollViewer>
</Grid>

      

A coworker pointed out that my problem is because controls like ListBoxes and DataGrids contain ScrollViewers themselves, this makes sense. His suggestion (which will work, but we both agree, seems more complicated than it should be) is to catch and reload the scroll event in the code behind (and probably have to deal with calculating the scrolling offset). so it can bubble up to "MainScrollViewer".

EDIT 2: It seems the only way to achieve this is to use code to handle the PreviewMouseWheel event in the parent. This works, but how can I implement the same thing for panning (swiping with my finger across the touchscreen)?

+3


source to share


3 answers


Use ScrollViewer PreviewMouseWheel function and ScrollToVerticalOffset method ...



private void ScrollViewerOnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
    var scv = sender as ScrollViewer;
    if (scv == null) return;
    scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
    e.Handled = true;
}

      

+4


source


Create bubble scrolling behavior for your scrolling:

using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;

public sealed class BubbleScrollEvent : 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)
    {
        if (!e.Handled)
        {
            e.Handled = true;
            var e2 = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta) { RoutedEvent = UIElement.MouseWheelEvent };
            AssociatedObject.RaiseEvent(e2);
        }
    }
}

      



Add this behavior to your scrollviewer:

 <ScrollViewer x:Name="Scroller">
                    <i:Interaction.Behaviors>
                        <ViewAddons:BubbleScrollEvent />
                    </i:Interaction.Behaviors>

      

+3


source


For starters, make sure you are using technology that already exists. This might solve your problem.

<Grid HorizontalAlignment="Left" Height="300" Margin="10,10,0,0" VerticalAlignment="Top" Width="497" ScrollViewer.VerticalScrollBarVisibility="Visible" />

      

Although this won't fix the problem and I know it sounds weird: set the background color of the grid AND the problem object to # 00000000. (If no color / brush is assigned yet)

<Grid HorizontalAlignment="Left" Height="300" Margin="10,10,0,0" VerticalAlignment="Top" Width="497" Background="#00000000"/>

      

I know its strange, but when I have these problems it works every time. I have no idea why this works. Something to do with transparency.

0


source







All Articles