【问题标题】:Resize text size of a label when the text gets longer than the label size?当文本长于标签大小时调整标签的文本大小?
【发布时间】:2012-03-20 15:03:05
【问题描述】:

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

label1.Size = new Size(200, 32);
label1.AutoSize = false;

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

【问题讨论】:

  • 如果文本变得太长而无法在表单上显示,您期望会发生什么?
  • 请为GUI框架、WinForms或asp.net等设置标签。
  • @M.Babcock 我希望它变得更小,以便适合标签

标签: c# text label size


【解决方案1】:

你可以在下面使用我的代码 sn-p。系统需要一些循环来根据文本大小计算标签的字体。

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

【讨论】:

  • 当标签变大,字体需要变大时,需要添加代码。
  • 循环是找到合适尺寸的低效方法。 jwaliszko's answerAndro72's answer 通过测量一次并计算比率来避免循环。如果Graphics 不可用,我确实喜欢使用TextRenderer.MeasureText。如果比率计算导致标签稍微太大,其他答案之一之后执行类似的操作可能是明智的。
【解决方案2】:

基于@brgerner 提供的article,我将在此处提供替代实现,因为标记为答案的实现不如下面的那么高效也不完整:

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

【讨论】:

    【解决方案3】:

    标签缩放

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

    @ToolmakerSteve 在 cmets 中指出的 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);
    }
    

    【讨论】:

    • 可以使用Windows.Forms.TextRenderer.MeasureText;不需要fakeImagegraphics
    【解决方案4】:

    我使用以下加权缩放技巧来提供良好的拟合,即在拟合高度和拟合宽度之间进行加权权衡。它在 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
    

    【讨论】:

    • 请说明加权缩放何时合适/有用。对于最常见的用法,必须缩小大小,直到文本适合 both 尺寸;什么时候会想在这里使用这种方法?
    【解决方案5】:

    我认为最简单的方法是检查渲染大小,如果大于实际标签大小,则减小标签的字体大小。

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

    【讨论】:

    • 您是否阅读了任何已经存在的答案,看看他们是否做了类似的事情? [提示:有类似的答案,而且他们做得更好,因为他们重复测试直到找到合适的,或者更好的是,他们估计什么尺寸适合测量一次后。]
    【解决方案6】:

    在@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 并且是 dockedanchored

    【讨论】:

      【解决方案7】:

      这个方法对我有用

      您只需减小字体大小,直到达到您想要的宽度。

      while (label1.Width >150 )
      {
          label1.Font = new Font(label1.Font.FontFamily, label1.Font.Size - 0.5f, label1.Font.Style);
      }
      

      【讨论】:

        【解决方案8】:

        首先,每当文本更改时,您都需要一个事件:

        lbl.TextChanged += new EventHandler(Label_TextChanged);
        

        然后你改变事件内的字体以适应:

        private void Label_TextChanged(object sender, EventArgs e)
        {
            Label lbl = (Label)sender;
            if (lbl.Image != null) return;
            using (Graphics cg = lbl.CreateGraphics())
            {
                SizeF lblsize = new SizeF(lbl.Width, lbl.Height);
                SizeF textsize = cg.MeasureString(lbl.Text, lbl.Font, lblsize);
                while (textsize.Width > lblsize.Width - (lblsize.Width * 0.1))
                {
                    lbl.Font = new Font(lbl.Font.Name, lbl.Font.Size - 1, lbl.Font.Style);
                    textsize = cg.MeasureString(lbl.Text, lbl.Font, lblsize);
                    if (lbl.Font.Size < 6) break;
                }
            }
        }
        

        这样您就可以使用较小的字体。 当涉及图像时,我会跳过。 我也停到5号。 我以-1的间隔收缩。 -0.5 也可以。 我认为 10% 的控制区域是不可用的“边界”——效果很好。 这种技术会起作用,但不要期望将大文本转换成小标签。 如果您没有图像,您可以使用控件而不是标签,也可以应用于按钮和文本框。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-01-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-27
          相关资源
          最近更新 更多