C# 当文本长于标签大小时调整标签的文本大小?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9527721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 07:45:38  来源:igfitidea点击:

Resize text size of a label when the text gets longer than the label size?

c#textlabelsize

提问by Murhaf Sousli

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

我有一个显示文件名的标签。我必须设置AutoSize标签来False进行设计。
所以当文件名文本长于标签大小时..它像图片中一样被剪掉了。

enter image description here

在此处输入图片说明

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?

当文本长于标签大小时,如何自动调整文本大小以适应标签大小?

采纳答案by bnguyen82

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);
}

回答by jwaliszko

Based on the articleprovided 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:

根据@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);
            }
        }
    }
}

and the usage:

和用法:

val label = new Label();
label.Paint += (sender, e) => FontWizard.OnPaint(sender, e, text);

回答by Andro72

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);
}

TextRenderer Approach pointed out by @ToolmakerSteve in the comments

@ToolmakerSteve 在评论中指出的 TextRenderer 方法

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);
}

回答by Chiel ten Brinke

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.

我使用以下加权缩放技巧来提供良好的拟合,即在拟合高度和拟合宽度之间进行加权权衡。它在 VB .net 中,但我认为您可以轻松转换为 C#。

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

回答by user8156190

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) {

私有无效标签3_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){

        lbl.Font = new System.Drawing.Font(lbl.Font.Name, lbl.Font.Size - 1, lbl.Font.Style);

    }

回答by SubqueryCrunch

With inspiration from @bnguyen82 i came up with something that works all the way.

在@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: In order for this to work the label needs to have AutoSize = falseand either to be dockedor anchored.

PS:为了使其工作,标签需要具有AutoSize = false并且要么是docked要么anchored