Kenny
Kenny

Reputation: 1152

Center text vertically (TextBlock)

I'm struggling to vertically center text using TextBlock. I know that it adds extra space above the space in case you use accents but why it isn't consistent with the space below then? There's a few extra pixels.

bad vertically center image

<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,40,0,0" Background="#FF191919" BorderThickness="1" BorderBrush="#FFBF0077">
    <Grid Width="41" HorizontalAlignment="Left" Padding="0" BorderThickness="0,0,1,0" BorderBrush="#FFBF0077">
        <TextBlock x:Name="TextBlockLocalScore" Text="0" FontFamily="Courier New" Foreground="#FF007AFF" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" />
    </Grid>
    <Grid Padding="4,8" BorderThickness="8,0" Width="104">
        <TextBlock x:Name="TextBlockMinutesLeft" Text="00" HorizontalAlignment="Left" FontSize="36" VerticalAlignment="Center" FontFamily="Segoe UI Light" FontWeight="Light" TextAlignment="Center" Height="27" TextLineBounds="Tight" Margin="0,0,4,0" />
        <TextBlock x:Name="TextBlockSecondsLeft" Text="30" HorizontalAlignment="Right" FontSize="36" VerticalAlignment="Center" FontFamily="Segoe UI Light" FontWeight="Light" OpticalMarginAlignment="TrimSideBearings" TextAlignment="Center" Height="27" TextLineBounds="Tight" />
    </Grid>
    <Grid Width="41" HorizontalAlignment="Right" Padding="0,8" BorderThickness="1,0,0,0" BorderBrush="#FFBF0077">
        <TextBlock x:Name="TextBlockRemoteScore"  Text="0" HorizontalAlignment="Center" FontSize="36" VerticalAlignment="Center" FontFamily="Segoe UI Light" FontWeight="Light" OpticalMarginAlignment="TrimSideBearings" TextAlignment="Center" Height="27" TextLineBounds="Tight" Foreground="#FFFF3B30" />
    </Grid>
</StackPanel>

I've played with Line Height and Text Line Bounds but I can't why a way to make the text still vertical centered once I change the font.

Updated code to reproduce issue:

<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Center" Margin="0,100,0,0" Background="#FF191919" BorderThickness="1" BorderBrush="#FFBF0077">
    <Grid Width="51" HorizontalAlignment="Left" Padding="0" BorderThickness="0,0,1,0" BorderBrush="#FFBF0077">
        <TextBlock Text="0" FontFamily="Courier New" FontSize="36" Foreground="#FF007AFF" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" />
    </Grid>
    <StackPanel Padding="4" BorderThickness="8,0" Orientation="Horizontal">
        <TextBlock Text="01" FontFamily="Courier New" FontSize="36" TextAlignment="Left" VerticalAlignment="Center" Margin="0,0,4,0" />
        <TextBlock Text="11" FontFamily="Courier New" FontSize="36" TextAlignment="Right" VerticalAlignment="Center" />
    </StackPanel>
    <Grid Width="51" HorizontalAlignment="Right" Padding="0,8" BorderThickness="1,0,0,0" BorderBrush="#FFBF0077">
        <TextBlock Text="0" FontFamily="Courier New" FontSize="36" Foreground="#FF007AFF" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" />
    </Grid>
</StackPanel>

Upvotes: 2

Views: 2940

Answers (2)

Nico Zhu
Nico Zhu

Reputation: 32785

I have tested your code and reproduced this behavior. If your have not set the height and width of TextBlock, it will set them based on your text font size automatically . For example, If the FontFamily is Courier New and the font size is 25, and the actual width and height of TextBlock is 16.00244140625 , 29.3203125. It will generate deviation when you center the text vertically. However, you could manual correct it via modifying the Padding just like the follow

enter image description here

Upvotes: 1

Justin XL
Justin XL

Reputation: 39006

You should have a play with these two properties. In your case you are probably more interested in TextLineBounds.

<TextBlock Text="80" FontSize="40" TextLineBounds="Tight" OpticalMarginAlignment="TrimSideBearings" />

Update

I am not sure if your screenshot is 100% accurate. I have used your code to produce the following pictures. Note I have scaled them up by 10 times.

<Grid Width="41" HorizontalAlignment="Left" Padding="0" BorderThickness="0,0,1,0" BorderBrush="#FFBF0077">
    <TextBlock x:Name="TextBlockLocalScore" TextLineBounds="Full" Text="80" FontFamily="Courier New" FontSize="36" Foreground="#FF007AFF" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" />
    <Rectangle UseLayoutRounding="False" HorizontalAlignment="Center" Fill="White" Height="10" VerticalAlignment="Top" Width="1" Margin="-21,0,0,0" />
    <Rectangle UseLayoutRounding="False" HorizontalAlignment="Center" Fill="White" Height="10" VerticalAlignment="Bottom" Width="1" Margin="-21,0,0,0" />
</Grid>

With TextLineBounds set to Tight

enter image description here

With TextLineBounds set to Full

enter image description here

Yes, on the first one, there's still a tiny little gap (about 0.3 epx) between the bottom edge of number 8 and the Line, but this is mostly due to layout rounding and effective pixel snapping. I don't think it's noticeable to human eyes. :)

P.S. You cannot purely rely on checking the visuals from Blend Designer as sometimes the artboard doesn't get updated on time to give you the correct result. You should always run your app and check from there.

Upvotes: 3

Related Questions