web-dev-qa-db-de.com

Textgröße eines Labels ändern, wenn der Text länger als die Labelgröße wurde?

Ich habe ein Label, das den Dateinamen anzeigt. Ich musste AutoSize des Labels für das Design auf False setzen.
Wenn der Dateiname-Text länger als die Etikettengröße wurde, wurde er wie im Bild geschnitten.

enter image description here

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

Wie kann ich die Größe des Texts automatisch an die Etikettengröße anpassen, wenn der Text länger als die Etikettengröße ist?

20
Murhaf Sousli

Sie können mein Code-Snippet unten verwenden. Das System benötigt einige Schleifen, um die Schriftart des Labels basierend auf der Textgröße zu berechnen. 

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

Beschriftungsskalierung

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

    }
8
Andro72

Basierend auf dem von @brgerner bereitgestellten article werde ich hier die alternative Implementierung bereitstellen, da die als Antwort markierte Version nicht so effizient oder vollständig ist wie die folgende:

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

und die Verwendung:

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

Mit der Inspiration von @ bnguyen82 bin ich auf etwas gekommen, das den ganzen Weg funktioniert.

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: Damit dies funktioniert, muss das Label AutoSize = false und entweder docked oder anchored sein.

0
SubqueryCrunch

Ich verwende den folgenden gewichteten Skalierungs-Trick, um eine gute Anpassung bereitzustellen, d. H. Ein gewichteter Kompromiss wird zwischen dem Anpassen der Höhe und dem Anpassen der Breite vorgenommen. Es ist in VB .net, aber ich denke, Sie können es leicht in C # übersetzen.

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
0