...some contr...">

Reserve Space for ScrollViewer

I have a ScrollViewer around some controls and

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

by default, it does not reserve the space required to display the scroll bar. This means that when it is shown / hidden, my controls are compressed and expanded again.

How to reserve a space for a scrollbar? Is there some kind of property or style that I can establish, which means when it is not necessary that it is hidden and not collapsed? Or do my child controls need to be “populated” or something in their right side to leave space? Should I put the controls in a grid and create a scroll size column for the scroll bar to be displayed (somehow)?

I wish he was still invisible when not required. I just would like him to make the best reservation for the place when it is.

Thanks to everyone.

+4
source share
2 answers

here is an example

this will reserve the scrollbar space when it is not visible using the border as a 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 to reserve space for the scroll bar. you can select the item of your choice

Define as a reusable pattern.

<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

+8
source

If you want to ScrollVieweralways "reserve a place" for your own ScrollBar, you can do this:

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

ScrollBar, , , , .

0

Source: https://habr.com/ru/post/1548048/


All Articles