不使用图形对象来测量字符串?

问题描述 投票:0回答:5

我使用像素作为字体的单位。在一个地方,我正在执行点击测试来检查用户是否在屏幕上某些文本的边框内单击。我需要使用像

MeasureString
这样的东西。不幸的是,执行命中测试的代码位于库深处,无法访问
Graphics
对象,甚至无法访问
Control

如何在不使用

Graphics
类的情况下获取给定字体的字符串的边界框?当我的字体以像素为单位时,为什么我还需要
Graphics
对象?

c# text fonts gdi+
5个回答
52
投票

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


26
投票

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

public static class GraphicsHelper
{
    public static SizeF MeasureString(string s, Font font)
    {
        SizeF result;
        using (var g = Graphics.FromHwnd(IntPtr.Zero))
        {
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
            result = g.MeasureString(s, font, int.MaxValue, StringFormat.GenericTypographic);
        }

        return result;
    }
}

根据您的情况设置位图的 dpi 可能是值得的。


12
投票
@NerdFury 答案中的

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

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

1
投票

这个例子很好地说明了 FormattedText 的使用。 FormattedText 提供了在 Windows Presentation Foundation (WPF) 应用程序中绘制文本的低级控制。您可以使用它来测量具有特定字体的字符串的宽度,而无需使用 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库。


1
投票

这可能不是其他人的重复,但我的问题也是不需要的 Graphics 对象。听了上面的挫败感后,我简单地尝试了一下:

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

(其中“content”是要测量的字符串,cardfont 是它所在的字体)

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

© www.soinside.com 2019 - 2024. All rights reserved.