I have a label that shows the file name .. I had to set AutoSize
of the label to False
for designing.
So when the file name text got longer than label size.. it got cut like in the picture.

label1.Size = new Size(200, 32);
label1.AutoSize = false;
How do I re-size the text automatically to fit the label size, when the text is longer than the label size?
You can use my code snippet below. System needs some loops to calculate the label's font based on text size.
while(label1.Width < System.Windows.Forms.TextRenderer.MeasureText(label1.Text,
new Font(label1.Font.FontFamily, label1.Font.Size, label1.Font.Style)).Width)
{
label1.Font = new Font(label1.Font.FontFamily, label1.Font.Size - 0.5f, label1.Font.Style);
}
Label scaling
private void scaleFont(Label lab)
{
Image fakeImage = new Bitmap(1, 1); //As we cannot use CreateGraphics() in a class library, so the fake image is used to load the Graphics.
Graphics graphics = Graphics.FromImage(fakeImage);
SizeF extent = graphics.MeasureString(lab.Text, lab.Font);
float hRatio = lab.Height / extent.Height;
float wRatio = lab.Width / extent.Width;
float ratio = (hRatio < wRatio) ? hRatio : wRatio;
float newSize = lab.Font.Size * ratio;
lab.Font = new Font(lab.Font.FontFamily, newSize, lab.Font.Style);
}
Based on the article provided by @brgerner, I'll provide the alternative implementation here, as that one marked as an answer is not so efficient nor complete as this one below:
public class FontWizard
{
public static Font FlexFont(Graphics g, float minFontSize, float maxFontSize, Size layoutSize, string s, Font f, out SizeF extent)
{
if (maxFontSize == minFontSize)
f = new Font(f.FontFamily, minFontSize, f.Style);
extent = g.MeasureString(s, f);
if (maxFontSize <= minFontSize)
return f;
float hRatio = layoutSize.Height / extent.Height;
float wRatio = layoutSize.Width / extent.Width;
float ratio = (hRatio < wRatio) ? hRatio : wRatio;
float newSize = f.Size * ratio;
if (newSize < minFontSize)
newSize = minFontSize;
else if (newSize > maxFontSize)
newSize = maxFontSize;
f = new Font(f.FontFamily, newSize, f.Style);
extent = g.MeasureString(s, f);
return f;
}
public static void OnPaint(object sender, PaintEventArgs e, string text)
{
var control = sender as Control;
if (control == null)
return;
control.Text = string.Empty; //delete old stuff
var rectangle = control.ClientRectangle;
using (Font f = new System.Drawing.Font("Microsoft Sans Serif", 20.25f, FontStyle.Bold))
{
SizeF size;
using (Font f2 = FontWizard.FlexFont(e.Graphics, 5, 50, rectangle.Size, text, f, out size))
{
PointF p = new PointF((rectangle.Width - size.Width) / 2, (rectangle.Height - size.Height) / 2);
e.Graphics.DrawString(text, f2, Brushes.Black, p);
}
}
}
}
and the usage:
val label = new Label();
label.Paint += (sender, e) => FontWizard.OnPaint(sender, e, text);
I use the following weighted scaling trick to provide a good fit, i.e. a weighted tradeoff is made between fitting the height and fitting the width. It's in VB .net, but I think you can translate to C# easily.
Function shrinkFontToFit(f As Font, text As String, requiredsize As SizeF) As Font
Dim actualsize As SizeF = TextRenderer.MeasureText(text, f)
Return New Font(f.FontFamily, f.Size * (requiredsize.Width + requiredsize.Height ) _
/ (actualsize.Width + actualsize.Height), f.Style, GraphicsUnit.Pixel)
End Function
With inspiration from @bnguyen82 i came up with something that works all the way.
public static void ScaleLabel(Label label, float stepSize = 0.5f)
{
//decrease font size if text is wider or higher than label
while (lblTextSize() is Size s && s.Width > label.Width || s.Height > label.Height)
{
label.Font = new Font(label.Font.FontFamily, label.Font.Size - stepSize, label.Font.Style);
}
//increase font size if label width is bigger than text size
while (label.Width > lblTextSize().Width)
{
var font = new Font(label.Font.FontFamily, label.Font.Size + stepSize, label.Font.Style);
var nextSize = TextRenderer.MeasureText(label.Text, font);
//dont make text width or hight bigger than label
if (nextSize.Width > label.Width || nextSize.Height > label.Height)
break;
label.Font = font;
}
Size lblTextSize() => TextRenderer.MeasureText(label.Text,
new Font(label.Font.FontFamily, label.Font.Size, label.Font.Style));
}
PS: In order for this to work the label needs to have AutoSize = false
and either to be docked
or anchored
.
private void setFontSize(Label label1)
{
if (label1.Text.Length > 200)
{
label1.Font = new Font(label1.Font.FontFamily, 24f, label1.Font.Style);
}
else if (label1.Text.Length > 100)
{
label1.Font= new Font(label1.Font.FontFamily, 36f, label1.Font.Style);
}else
label1.Font = new Font(label1.Font.FontFamily, 48f, label1.Font.Style);//My orginal font size is 48f.
}
You can edit for yourself.
private void button1_Click(object sender, EventArgs e)
{
Panel.Text = "Your Text";
setFontSize(Panel);
}
I think the easiest way could be to check the render size and if it is greater than the actual label size, decrease the fontsize of the label.
private void label3_Paint(object sender, PaintEventArgs e) {
Size sz = TextRenderer.MeasureText(label1.Text, label1.Font, label1.Size, TextFormatFlags.WordBreak);
if (sz.Width > label1.Size.Width || sz.Height > label1.Size.Height)
{
DecreaseFontSize(label1);
}
}
public void DecreaseFontSize(Label lbl) {
lbl.Font = new System.Drawing.Font(lbl.Font.Name, lbl.Font.Size - 1, lbl.Font.Style);
}
来源:https://stackoverflow.com/questions/9527721/resize-text-size-of-a-label-when-the-text-got-longer-than-the-label-size