Home > Back-end >  Show vertical scrollbar within a TextWrapping TextBox
Show vertical scrollbar within a TextWrapping TextBox

Time:07-30

I have an WPF UserControl. Within, I have a Grid which contains only a row with a few columns. There is a TextBox which I has its TextWrapping set to Wrap using an style:

<Style x:Key="TextBlockStyle" TargetType="{x:Type TextBox}">
    <Setter Property="Background" Value="{x:Null}" />
    <Setter Property="BorderBrush" Value="{x:Null}" />
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="Padding" Value="0" />
    <Setter Property="IsReadOnly" Value="True" />
    <Setter Property="IsTabStop" Value="False" />
    <Setter Property="VerticalAlignment" Value="Center" />
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="TextWrapping" Value="Wrap" />
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="{x:Null}" />
        </Trigger>
    </Style.Triggers>
</Style>

And the Grid:

<Grid Height="auto" >
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>

        <TextBox Grid.Column="1" 
                 Style="{StaticResource TextBlockStyle}"
                 VerticalScrollBarVisibility="Auto"
                 HorizontalAlignment="Left"
                 Margin="5"
                 Text="{Binding Path=Text}"
                 Foreground="{Binding Path=ForegroundColor}">
        </TextBox>
</Grid>

What happens is that the vertical scroll bar is never shown. Instead, the text is cut off vertically.

CodePudding user response:

The issue is that your row as well as your column definition for the TextBox use Auto as size:

If a child element is added to a column within a Grid, and the column has its Width property set to Auto, the child will be measured without restrictions. This behavior can prevent horizontal scroll bars from displaying if a ScrollViewer is being used, as the child element is measured as unbounded. For purposes of display, the child is clipped rather than scrolled.

This is exactly what happens in your case. Through the unbounded width, the TextBox expands horizontally until it fits its content and that is way beyond the available (visible) space, so the rest is cut off. The same applies to the unbounded height, in case you fixed the width only. Consequently, all the content technically fits in and no scrollbars are shown.

You should use star sizing in this case to size the TextBox in the remaining space.

Columns and rows that are defined within a Grid can take advantage of Star sizing to distribute remaining space proportionally.

This way, its size is bounded by the remaining space and if there is not enough space available for the whole text, the scollbars are shown. Here I just replaced Auto sizes with * which works:

<Grid.RowDefinitions>
   <RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
   <ColumnDefinition Width="auto"/>
   <ColumnDefinition Width="*"/>
   <ColumnDefinition Width="auto"/>
   <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

Of course, you have to transfer this to fit your layout requirements.

  • Related