Change font size if text exceeds Textblock border

I have a text block with Width = 511, Height = 159. FontSize = 28. I want to change the font size if the text is larger than the text block so that all the text is displayed. Is there any way to do this? Formula maybe?

+7
source share
5 answers

This solution involves the use of ViewBox, I think that with the help of the Wpf conversion functions there is no need to change the font size for the text. Almost the same result can be archived using conversion (in this case, ViewBox).

Instead of putting your TextBlock inside the ViewBox, change its template and place the control where the text appears inside the ViewBox, something like:

<ControlTemplate TargetType="{x:Type TextBox}"> <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true"> <Viewbox HorizontalAlignment="Left"> <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </Viewbox> </Microsoft_Windows_Themes:ListBoxChrome> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> 

Now you get a control that changes its text to fit into the available space thanks to WPF.

An example is also given.

text example

+2
source

I'm not sure about WPF, but in WinForms you can use the MeasureString method to measure the size of the strings in a given font. Thus, whenever the contents of a text block change, you just need to use this method, and if the text is larger than the text block, reduce the font size and measure again.

(now, after I wrote this, I think there should be a simpler method for this)

0
source

It depends on what font you are using, for example, Courier New is designed to make each character the same width, so if you examine what width is for a character, you can use the get length function for the string (giving you length in characters) and from there calculate its width in pixels. If its width exceeds 511px, you adjust the size accordingly.

If you use a different font, such as Arial, you can do the same, and if you really want it to be accurate, you can group the alphabet into narrow letters, for example, "i", "l", etc., and middle letters like 't' and thick letters like 'o' and capitals. Then you get the number of narrow, medium and thick letters and calculate the size of this data, but personally it is too much for me.

Hope this was helpful.

Edit: Ignore this, I just read about the measurement function. This is a lot less effort than my suggestion.

0
source

Here is what I came up with. Make sure that you handle the case of a font size of -1.0.

  private static double GetFontSize(TextBox textBox) { double fontSize = textBox.FontSize; FormattedText ft = new FormattedText(textBox.Text, CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(textBox.FontFamily, textBox.FontStyle, textBox.FontWeight, textBox.FontStretch), fontSize, textBox.Foreground); while (textBox.Width < ft.Width) { fontSize -= 1; if (fontSize < 0) return -1.0; ft = new FormattedText(textBox.Text, CultureInfo.CurrentCulture, System.Windows.FlowDirection.LeftToRight, new Typeface(textBox.FontFamily, textBox.FontStyle, textBox.FontWeight, textBox.FontStretch), fontSize, textBox.Foreground); } return fontSize; } 
0
source

Edit: I have to look at the tags before posting. I do not know what WPF can offer to solve this problem.

I have no evidence to support this, but it seems that (also for fonts with a variable width, at least all installed on my machine):

  • Font size has a linear relationship with the width of a given string
  • A font size of 0 results in a width of 0

This means that you could probably use MeasureString once for maximum font size and then interpolate to find the optimal font size.

There are some โ€œpixel hitsโ€ on this โ€œlinear road,โ€ so you can drop a few pixels, but this is a good alternative to measure measures.

0
source

All Articles