Изменить размер текста надписи, когда текст становится длиннее, чем размер надписи?
У меня есть метка, которая показывает имя файла. Мне нужно было установить AutoSize
метки на False
для проектирования.
Поэтому, когда текст названия файла больше, чем размер метки, он обрезается, как на картинке.
![enter image description here]()
label1.Size = new Size(200, 32);
label1.AutoSize = false;
Как изменить размер текста автоматически, чтобы он соответствовал размеру метки, когда текст длиннее размера метки?
Ответы
Ответ 1
Ниже приведен фрагмент кода. Системе нужны некоторые циклы для расчета шрифта метки на основе размера текста.
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);
}
Ответ 2
Масштабирование этикетки
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);
}
Подход TextRenderer, указанный @ToolmakerSteve в комментариях
private void ScaleFont(Label lab)
{
SizeF extent = TextRenderer.MeasureText(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);
}
Ответ 3
Основываясь на статье, предоставленной @brgerner, я приведу здесь альтернативную реализацию, поскольку помеченная как ответ не так эффективна и полна, как эта ниже:
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);
}
}
}
}
и использование:
val label = new Label();
label.Paint += (sender, e) => FontWizard.OnPaint(sender, e, text);
Ответ 4
Я использую следующий взвешенный скейлинг-трюк, чтобы обеспечить хорошую подгонку, т.е. взвешенный компромисс между установкой высоты и установкой ширины. Это в VB.net, но я думаю, что вы можете легко перевести на С#.
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
Ответ 5
По вдохновению от @bnguyen82 я придумал что-то, что работает все время.
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: для того, чтобы это работало, этикетка должна иметь AutoSize = false
и быть либо docked
, либо anchored
.
Ответ 6
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.
}
Вы можете редактировать для себя.
private void button1_Click(object sender, EventArgs e)
{
Panel.Text = "Your Text";
setFontSize(Panel);
}
Ответ 7
Я думаю, что самый простой способ - проверить размер рендеринга, и если он больше фактического размера метки, уменьшите шрифт метки.
private void label3_Paint (отправитель объекта, 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);
}