Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reserve Space for ScrollViewer

I've got a ScrollViewer round some controls and with

<ScrollViewer VerticalScrollBarVisibility="Auto">
   ...some controls here...
</ScrollViewer>

by default it doesn't reserve the space needed to show the scroll bar. This means that when it's shown/hidden my controls are squished and expanded again.

How can I reserve space for the scroll bar? Is there some kind of property or style I can set which means when it's not needed it's set to hidden rather than collapsed? Or do my child controls need a 'padding' or something on their right hand side to leave the space? Should I put the controls in a grid and make a scroll viewer sized column for the scroll bar to be displayed in (somehow)?

I would like it still to be invisible when not required I would just like the best way of making it reserve the space for when it is.

Thanks all.

like image 625
GoldieLocks Avatar asked Jul 11 '14 09:07

GoldieLocks


1 Answers

here is a sample

this will reserve the scroll bar space when it is not visible by using a border as placeholder

    <ScrollViewer VerticalScrollBarVisibility="auto" x:Name="scroll">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="auto" />
            </Grid.ColumnDefinitions>
            <Border Background="LightGoldenrodYellow"
                    Height="300" />
            <Border Grid.Column="1"
                    Width="{x:Static SystemParameters.VerticalScrollBarWidth}">
                <Border.Style>
                    <Style TargetType="Border">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding ComputedVerticalScrollBarVisibility, ElementName=scroll}"
                                         Value="Visible">
                                <Setter Property="Visibility"
                                        Value="Collapsed" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Border.Style>
            </Border>
        </Grid>
    </ScrollViewer>

the first border is the content and the second border is the placeholder for reserving the space for scrollbar. you can choose to replace with element of your choice

Define as a reusable template

<Grid>
    <Grid.Resources>
        <ControlTemplate x:Key="ReservedSpaceScroller" TargetType="ContentControl">
            <ScrollViewer VerticalScrollBarVisibility="auto"
                          x:Name="scroll">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition Width="auto" />
                    </Grid.ColumnDefinitions>
                    <ContentPresenter />
                    <Border Width="{x:Static SystemParameters.VerticalScrollBarWidth}"
                            x:Name="placeholder" Grid.Column="1" />
                </Grid>
            </ScrollViewer>
            <ControlTemplate.Triggers>
                <DataTrigger Binding="{Binding ComputedVerticalScrollBarVisibility, ElementName=scroll}"
                             Value="Visible">
                    <Setter TargetName="placeholder"
                            Property="Visibility"
                            Value="Collapsed" />
                </DataTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Grid.Resources>

    <ContentControl Template="{StaticResource ReservedSpaceScroller}">
        <Border Background="LightGoldenrodYellow"
                Height="300" />
    </ContentControl>
</Grid>

result

result

like image 67
pushpraj Avatar answered Oct 27 '22 22:10

pushpraj