Search code examples
c#wpf.net-4.0framescrollviewer

Disable scrolling in ScrollViewer child of a Frame which has a ScrollViewer as parent


State

I have a Page (Page_Child) with a ScrollViewer (ScrollViewer_Child) in a Frame (Frame_Parent) which is the child of my parent ScrollViewer (ScrollViewer_Parent).

<ScrollViewer Name="ScrollViewer_Parent">
    <StackPanel>
        <Frame Name="Frame_Parent">
            <Frame.Content>

                <Page Name="Page_Child">
                    <ScrollViewer Name="ScrollViewer_Child">
                        <!-- Page Content -->
                    </ScrollViewer>
                </Page>

            </Frame.Content>
        </Frame>
        <!-- ... -->
    </StackPanel>
</ScrollViewer>

Problem

What I try to achieve is to disable the ScrollViewer in the Frame as the parent ScrollViewer can handle all of the seizing thanks to the not fixed height of the Frame. - Or at least let the parent continue scrolling when the child reached the top or the bottom.

Sadly I can't use any external resources or libraries, nor can I remove the child ScrollViewer as it's visualized somewhere else in my application.

Question

Is there a way of telling the frame content to disable scrolling or how to archive the continues scrolling through the frame?


Solution

  • If you were able to use external libraries you could use the behaviour here: BubbleScrollEvent Behaviour, but as you cannot you can simply just write a similar thing but in the code behind;

    by attaching a method to the PreviewMouseWheel event of Frame which will route the event to the ScrollViewer like so:

    <ScrollViewer Name="ScrollViewer_Parent">
        <StackPanel PreviewMouseWheel="BubblePreviewMouseWheel">
            <Frame Name="Frame_Parent" PreviewMouseWheel="BubblePreviewMouseWheel" />
                ...
        </StackPanel>
    </ScrollViewer>
    
    
    private void BubblePreviewMouseWheel(object sender, MouseWheelEventArgs e)
    {
        e.Handled = true;
        var e2 = new MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta);
        e2.RoutedEvent = UIElement.MouseWheelEvent;
        ((UIElement)sender).RaiseEvent(e2);
    }
    

    Edit: Just realised it would raise the event to the StackPanel so you would need to attach BubblePreviewMouseWheel to the StackPanel as well.