Reputation: 832
There is method MeasureString
in Graphics
class, which helps user to find out, what size string has for specified font. But what if I want to know opposite - pick proper font size to fit text to width?
Actual use-case: I have multiple TextBlock
s, which should have same font size. I'd like to reduce size of text of all blocks, if width of any TextBlock
content exceeds certain value (for example, width of TextBlock
and some margin). For now, I'm using MeasureString
, to calculate some multiplier, which affects font size, but it seems, that it works not as I wanted it to - it leaves way too big gaps.
For example, I have limit of width 75 px, default font size 13, and string with width 125 px. (75/125) * 13 gives me 7.8 font size, which causes string to have 52 px in width (way much smaller than 75).
So, any good ways to do this?
Code In ViewModel:
private int _defaultFontSize = 13;
private int _maxStringSize = 75;
private string _text = "MoreMoreMore"; //test text, which exceeds 75 px
public double NameFontSize
{
get
{
var font = new Font("Segoe UI Light", _defaultNameFontSize);
double size;
using (var graphics = Graphics.FromImage(new Bitmap(1, 1)))
{
size = graphics.MeasureString(_text, font);
}
return Math.Min(1, _maxStringSize/size) * _defaultFontSize;
}
}
public string Text
{
get { return _text; }
}
In XAML
<TextBlock Text = "{Binding Text}" FontSize = "{Binding NameFontSize}"/>
Upvotes: 2
Views: 1118
Reputation: 128070
You're measuring with different font size units.
The System.Drawing.Font
constructor takes an em-size in points, which are 1/72
of an inch
emSize: ... The em-size, in points, of the new font.
while TextBlock.FontSize
is given in WPF units, which are 1/96
inch:
... An unqualified value is measured in device independent pixels. ...
Upvotes: 1
Reputation: 61
What about putting the TextBlock inside a ViewBox and let that take care of the scaling?
<Viewbox Width="75">
<TextBlock Text="{Binding Text}"/>
</Viewbox>
Upvotes: 1