Search code examples
c#xamluwpscrollview

How to have the scrollview affect the inner frame only, not whole app


In writing a XAML/UWP/C# app I have the MainPage.xaml, which contains a header menu (home|back|forward navigation and user display buttons), and page navigation menu (left side) split panel, other side of the split is a frame for displaying the pages.

Following is a simplified version of the code (Note that nowhere in this code is a ScrollView):

<Page
    x:Class="PowderTracks.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PowderTracks"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Width="1200"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <GridView Height="Auto">
        <StackPanel
            Width="Auto">
            <StackPanel x:Name="headerMenu" 
                    Orientation="Horizontal" 
                    Background="#FF016B3B"
                    Width="Auto"
                    Padding="0,0,0,0" >
                <Button x:Name ="HomeButton" 
                    Foreground="#FFC0FFC0" 
                    Margin="10,0,0,0" 
                    Background="#33016B3B">
                    <Image Source="Assets\Home.png" Width="64" />
                </Button>
                <Button x:Name ="BackButton" 
                    Foreground="#FFC0FFC0" 
                    Padding="0,0,0,0" 
                    Background="#33016B3B">
                    <Image Source="Assets\Back.png" Width="64" />
                </Button>
                <Button x:Name ="ForwardButton" 
                    Foreground="#FFC0FFC0" 
                    Padding="0,0,0,0" 
                    Background="#33016B3B">
                    <Image Source="Assets\Forward.png" Width="64" />
                </Button>
                <Button x:Name="btnFace" Background="#33016B3B">
                    <Image x:Name="userPic" Width="32" Height="32"/>
                    <Button.Flyout>
                        <Flyout>
                            <StackPanel>
                                <Image x:Name="foPic" Width="96" Height="96"/>
                                <TextBlock Name="foDisplayName" />
                                <TextBlock Name="foEmail" />
                            </StackPanel>
                        </Flyout>
                    </Button.Flyout>
                </Button>
                <TextBlock Name="lblUsername" 
                       x:FieldModifier="public"
                       Text="" 
                       Margin="10,0,0,0" 
                       Height="25" 
                       FontSize="18"
                       VerticalAlignment="Center" 
                       Foreground="#FFC0FFC0"
                />
                <ToggleSwitch x:Name="btnDatabase" 
                              Margin="50,0,0,0"
                              OffContent="TestDB" 
                              OnContent="LiveDB"
                              HorizontalAlignment="Right"
                              Visibility="Visible"
                              />

            </StackPanel>
            <SplitView  x:Name="svFrame"
                IsPaneOpen="True"
                    DisplayMode="Inline"
                    OpenPaneLength="80" Height="Auto" Width="1024">
                <UIElement.RenderTransform>
                    <MatrixTransform/>
                </UIElement.RenderTransform>
                <SplitView.Pane>
                    <StackPanel>
                        <Button Name="btnTracker" 
                                    Width="80" 
                                    Height="65" 
                                    Padding="0,0,0,0">
                            <Image Source="Assets\trackers.png" 
                                        Width="64"/>
                        </Button>
                        <Button Name="btnTasks"  
                                    Width="80">
                            <Image Source="Assets\tasksIcon.png" 
                                        Width="64"/>
                        </Button>
                        <Button Name="btnRFP"  
                                    Width="80">
                            <Image Source="Assets\proposals.png" 
                            Width="64"/>

                        </Button>
                        <Button Name="btnFM" 
                                    Width="80">
                            <Image Source="Assets\folderMachine.png" Width="64"/>
                        </Button>
                        <Button Name="btnClients"  
                                    Width="80" >
                            <Image Source="Assets\clients.png" 
                            Width="64"/>
                        </Button>
                        <Button Name="btnMaint" 
                                    Width="80" 
                                    Padding="0,0,0,0">
                            <Image Source="Assets\maintenance.png" 
                                        Width="64" 
                                        Margin="0,0,0,0"/>
                        </Button>
                    </StackPanel>
                </SplitView.Pane>
                <Frame x:Name="content" 
                            Padding="10,10,10,15" 
                            HorizontalAlignment="Left" 
                            Width="Auto" 
                            Height="Auto" 
                            VerticalAlignment="Top"/>
            </SplitView>
        </StackPanel>
    </GridView>

</Page>

(Click events were removed to make it just copy/paste.)

Anyway, the first opening page is the Proposals page (because this is the one I've been working on), and it is a long page with many controls. I want the scroll view to move the Proposals (or whatever pages come after) page without moving the header menu or the left-side navigation menu. Right now if I scroll the entire app scrolls, so the header and navigation menus scroll up as the page scrolls.

What I have tried: Placing the ScrollView on the <Frame x:Name...> panel - does not work. Placing the ScrollView on the Proposals Page in the top level StackPanel

<StackPanel Margin="0,0,10,27" 
            VerticalAlignment="Top" 
            ScrollViewer.VerticalScrollBarVisibility="Visible">

Doesn't work.

I've tried to follow the example on these sites:

https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.scrollviewer?view=winrt-18362 https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/scroll-controls

Thank you in advance.


Solution

  • GridView is usually used together with ItemTemplate and ItemsSource. This control is to quickly generate a batch of items with the same layout (such as the Windows Settings home page) based on the data set, rather than being used as a layout container. Here is the related document

    GridView is a combination of multiple controls. The reason why your application scrolls is because the GridView contains a ScrollViewer.

    Based on the code you provided, you can try this layout:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
    
        <StackPanel>
            <!-- Header Buttons -->
        </StackPanel>
    
        <SplitView Grid.Row="1">
    
            <SplitView.Pane>
                <!-- Pane List -->
            </SplitView.Pane>
    
            <SplitView.Content>
                <ScrollViewer>
                    <Frame x:Name="content"/>
                </ScrollViewer>
            </SplitView.Content>
    
        </SplitView>
    </Grid>
    

    This ensures that only the content inside the Frame will scroll.

    Thanks.