在文本更改为适合控件时调整文本大小

时间:2013-11-11 11:13:51

标签: c# winforms font-size

我正在尝试编写一个方法来调整文本字体大小,以便文本在控件中正确且完全可见。

我为此尝试的方法如下:

public static void FitControlFont(Control control)
        {
            if (control.Text.Length == 0)
            {
                return;
            }

            Font currentFont = control.Font;
            Graphics graphics = control.CreateGraphics();
            SizeF newSize = graphics.MeasureString(control.Text, control.Font);
            graphics.Dispose();

            float factorX = control.Width / newSize.Width;
            float factorY = control.Height / newSize.Height;
            float factor = factorX > factorY ? factorY : factorX;
            if (control.InvokeRequired)
            {
                control.Invoke(new MethodInvoker(delegate { control.Font = new Font(currentFont.Name, currentFont.SizeInPoints * factor); }));
            }
            else
            {
                control.Font = new Font(currentFont.Name, currentFont.SizeInPoints * factor);
            }
        }

上述方法效果很好但是, 我的问题虽然在这里,我如何使用文本作为多行? 我将文本放在一行(因为文本看起来非常小)。

我使用标签和按钮作为我在表单中使用的控件,当文本更改时,需要重新调整文本字体的大小。

1 个答案:

答案 0 :(得分:0)

这种方法可以完成这项工作。它可能看起来有点复杂,因为它必须以两种方式工作:如果初始文本太小则增加文本大小;如果初始文本太大则减少文本大小。

如果文字太小,它会增加直到它不能垂直放置(水平方向会自行分解)。

如果文字太大,它会减小,直到它适合控件的矩形。

控件必须是多行的。

您可以通过更改step变量的值来控制尺寸更改。

public static void FitControlFont(Control control)
{
    if (control.Text.Length == 0)
    {
        return;
    }

    Graphics graphics = control.CreateGraphics();
    Font newFont = (Font)control.Font.Clone();
    bool sizeFound = false; // to test if we already found the right size
    bool initiallyToSmall = false; // is the initial text to small (we will increase the font size) or too big (decrease the font size)
    float step = 1F; // increase/decrease step
    SizeF newSize = graphics.MeasureString(control.Text, newFont, new SizeF(control.Width, control.Height));
    if (newSize.Width <= control.Width && newSize.Height <= control.Height)
        initiallyToSmall = true;

    do
    {
        newSize = graphics.MeasureString(control.Text, newFont, new SizeF(control.Width, control.Height * 2));
        if (initiallyToSmall)
        {
            if (newSize.Height > control.Height)
            {
                newFont = new Font(control.Font.Name, newFont.SizeInPoints - step); // get previous size
                sizeFound = true;
            }
            else
                newFont = new Font(control.Font.Name, newFont.SizeInPoints + step);
        }
        else
        {
            if (newSize.Width <= control.Width && newSize.Height <= control.Height)
                sizeFound = true;
            else
                newFont = new Font(control.Font.Name, newFont.SizeInPoints - step);
        }

    } while (!sizeFound && newFont.SizeInPoints > 1 && newFont.SizeInPoints < 100);

    graphics.Dispose();

    if (control.InvokeRequired)
    {
        control.Invoke(new MethodInvoker(delegate { control.Font = newFont; }));
    }
    else
    {
        control.Font = newFont;
    }
}