Search code examples
c#xamlgrid-layoutwinui-3uwp-scrollviewer

Dynamically Setting ScrollViewer Height


I'm currently working on a WinUI 3 app, and I'm trying to have a StackPanel above and below a ScrollViewer which will always be visible (not depending on the size of the screen or the elements in the ScrollViewer):

<Grid Margin="30,30,30,30">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
                
    <StackPanel Orientation="Horizontal" Grid.Row="0">
        <TextBlock Name="projectNumber" Text="Project Number" Width="100" Margin="10,10,10,10" TextAlignment="Center"/>
        <TextBlock Name="taskName" Text="Task" Width="750" Margin="10,10,10,10" TextAlignment="Center"/>
        <TextBlock Name="dueDate" Text="Due Date" Width="100" Margin="10,10,10,10" TextAlignment="Center"/>
        <TextBlock Name="assignedBy"  Text="Assigned By" Width="100" Margin="10,10,10,10" TextAlignment="Center"/>
    </StackPanel>
    <Line Name="dividerLine" Stroke="DimGray" X1="0" Y1="0" X2="1130" Y2="0" Grid.Row="1"/>
    <ScrollViewer Name="scrollViewer" Grid.Row="2">
        <StackPanel>
            <ListView Name="tasksPanel" VerticalAlignment="Top" HorizontalAlignment="Left"/>
            <ListView Name="completeTasksPanel" VerticalAlignment="Top" HorizontalAlignment="Left"/>
        </StackPanel>
    </ScrollViewer>
    <StackPanel Orientation="Horizontal" Margin="0,10,0,10" Grid.Row="3">
        <TextBox/>
        <TextBox/>
        <TextBox/>
    </StackPanel>
</Grid>

However, the ScrollViewer element won't have its height set according to the screen, instead, it will take up as much space as the elements inside. I also tried setting the Grid.RowDefinitions with a set height instead of Auto, but it made no difference:

<RowDefinition Height="50"/>
<RowDefinition Height="3"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>

Solution

  • You should replace the StackPanel in the ScrollViewer with another Panel that doesn't measure its child elements with infinite vertical space, such as for example a Grid:

    <ScrollViewer Name="scrollViewer" Grid.Row="2">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <ListView Name="tasksPanel" VerticalAlignment="Top" HorizontalAlignment="Left"/>
            <ListView Grid.Row="1" Name="completeTasksPanel" VerticalAlignment="Top" HorizontalAlignment="Left"/>
        </Grid>
    </ScrollViewer>
    

    The other option is to specify a fixed height for the StackPanel.

    ScrollViewers and StackPanels don't work very well together because of the (infinite measurement) characteristics of the latter.