WPF TextBlock font resize to fill available space in a Grid
Asked Answered
M

7

63

I have some text that is displayed at run time in a textblock. I want the font size to be the biggest it can be to fill the area that is given. I think I have the textblock setup correctly to "autosize" and I try to increase the font size till the textblock is bigger than than its parent then decrease the font size by 1. The problem is I can't get the control to redraw/recompute its size.

Is the a better way to do that? Or is there a way I can make my method work?

Minestrone answered 17/2, 2010 at 16:57 Comment(0)
V
89

Wrap the TextBlock inside a ViewBox:

   <Grid>
    <Viewbox>
        <TextBlock TextWrapping="Wrap" Text="Some Text" />
    </Viewbox>
   </Grid>
Vedavedalia answered 17/2, 2010 at 17:10 Comment(4)
This fill all horizontal space... but how to do the same also for vertical space? I can not wrap the textblock text until it gets a very small font size.Levitus
This just made the text stretch to the height of the area it was in; making it end up being HUGE. And the wrapping never kicked it, it continued to flow off the right edge of my control.Hittel
Downvoted, Textwrapping does not work with viewbox unless the width of the textblock is set which defeats the entire idea of viewbox.Boastful
Actually, your downvote makes no sense :) how would your app be able to know when/where to crop if you give him no bounds ? Actually, viewbox does not fix dimensions, it adapts dynamically based on content which is why you must fix it. Don't forget you can use both techniques and set the textblock's width and length inside the viewbox. You could also use à binding on the Textblock's dimensions, but this could become a bit sophisticated x)Amphictyon
A
40

I had the same problem. You can use this to resize the fontsize of the textblock to fill the area when it has overflow.


<Viewbox StretchDirection="DownOnly" Stretch="Uniform">
    <TextBlock Text="{Binding Path=Title}" HorizontalAlignment="Center"/>
</Viewbox>

Affray answered 18/7, 2012 at 8:6 Comment(2)
Wow, I spent hours trying to find a solution to a similar problem using the Measure method and Width, ActualWidth, RenderWidth, but nothing worked ahahahahahahah I'd have never discovered the "DownOnly" property, thank you! :)Porphyry
You can change the Stretch value to Fill if you want the font to become narrower instead of smaller.Joann
M
12

The WPF ViewBox control can grow / shrink with its contents to the available space.

Just place your TextBlock within a ViewBox as;

<Viewbox Stretch="Uniform" Width="50" Height="50">
    <TextBlock Text="Test" />
</Viewbox>

ViewBox is typically scaled by its container.

Maclay answered 7/11, 2012 at 11:31 Comment(0)
M
11

I found a great way to do this using ViewBox:

 <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="50" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="100" />
    </Grid.ColumnDefinitions>
    <Viewbox Grid.Row="0" Grid.Column="0" Stretch="Uniform">
        <TextBlock Name="tbTest" Background="Yellow" Text="This is some text" />    
    </Viewbox>

    <ContentControl Grid.Column="0" Grid.Row="2">
        <TextBlock>This is some text</TextBlock>
    </ContentControl>
</Grid>
Minestrone answered 17/2, 2010 at 17:11 Comment(0)
P
3

Well, its not a "perfect" answer, but this is a quick hack (you can drop this into kaxaml and test it out):

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid Height="300" Background="green">  
  <Viewbox>
  <TextBlock Background="red" Text="Hurr"/>
  </Viewbox>
  </Grid>
</Page>

The ViewBox will enlarge any content to fill its container. The problem is that the TextBlock, while it sizes to its text, has padding at the top and bottom that you can't get rid of (without doing some heavy lifting). This might get you closer to what you want, tho.

Phlegmatic answered 17/2, 2010 at 17:18 Comment(0)
P
2

To ensure wrapping, you need to set the MaxWidth and/or MaxHeight of the TextBlock

<Viewbox StretchDirection="DownOnly" Stretch="Uniform">
      <TextBlock  MaxWidth="500" TextWrapping="Wrap" FontSize="30" VerticalAlignment="Center"
                  Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."/>

Penza answered 6/8, 2015 at 23:3 Comment(1)
Setting the width or height of the textblock makes the viewbox useless. The entire idea of viewbox is to adjust to changing screen sizes/resolutions. If you know the screen real estate you don't need a view box at allBoastful
S
0

I found a rather neat compromise of using the Viewbox, while keeping the text wrapping.

Just replace <ContentControl> and x:Type ContentControl with Button, Grid or whatever you need, that has a fixed size and is the parent.

<ContentControl>
    <Viewbox Stretch="Uniform" StretchDirection="DownOnly">
        <TextBlock Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}, Path=ActualWidth}" TextWrapping="WrapWithOverflow">some long random Text to be fitted</TextBlock>
    </Viewbox>
</ContentControl>
Shockproof answered 7/7, 2022 at 8:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.