在不使用Graphics对象的情况下测量String?

时间:2009-06-16 19:03:10

标签: c# text fonts gdi+

我使用像素作为我的字体的单位。在一个地方,我正在执行命中测试以检查用户是否在屏幕上的某些文本的边界矩形内点击了。我需要使用像MeasureString这样的东西。不幸的是,执行命中测试的代码深入到一个无法访问Graphics对象甚至是Control的库中。

如何在不使用Graphics类的情况下获取给定字体的字符串的边界框?为什么我的字体以像素为单位时甚至需要Graphics个对象?

5 个答案:

答案 0 :(得分:47)

如果您对System.Windows.Forms有引用,请尝试使用TextRenderer类。有一个静态方法(MeasureText),它接受字符串和字体并返回大小。 MSDN Link

答案 1 :(得分:23)

您无需使用用于渲染的图形对象来进行测量。您可以创建一个静态实用程序类:

public static class GraphicsHelper
{
    public static SizeF MeasureString(string s, Font font)
    {
        SizeF result;
        using (var image = new Bitmap(1, 1))
        {
            using (var g = Graphics.FromImage(image))
            {
                result = g.MeasureString(s, font);
            }
        }

        return result;
    }
}

根据您的具体情况,可能还值得设置位图的dpi。

答案 2 :(得分:10)

@NerdFury答案中的

MeasureString方法将提供比预期更高的字符串宽度。您可以找到here的附加信息。如果您只想测量物理长度,请添加以下两行:

g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
result = 
  g.MeasureString(measuredString, font, int.MaxValue, StringFormat.GenericTypographic);

答案 3 :(得分:1)

这个例子很好地说明了FormattedText的使用。 FormattedText为Windows Presentation Foundation(WPF)应用程序中的绘图文本提供低级控件。您可以使用它来测量具有特定Font的字符串的宽度,而无需使用Graphics对象。

public static float Measure(string text, string fontFamily, float emSize)
{
    FormattedText formatted = new FormattedText(
        item, 
        CultureInfo.CurrentCulture, 
        System.Windows.FlowDirection.LeftToRight, 
        new Typeface(fontFamily), 
        emSize, 
        Brushes.Black);

    return formatted.Width;
}

包括WindowsBase和PresentationCore库。

答案 4 :(得分:0)

这可能不是其他人的重复,但我的问题也是不受欢迎的Graphics对象。在听完上述挫折之后,我只是尝试了:

Size proposedSize = new Size(int.MaxValue, int.MaxValue);
TextFormatFlags flags = TextFormatFlags.NoPadding;
Size ressize = TextRenderer.MeasureText(content, cardfont, proposedSize, flags);

(其中'内容'是要测量的字符串,而不是它所在的字体)

......并且很幸运。我可以使用结果在VSTO中设置列的宽度。