2009-06-16 42 views
38

我使用像素作为我的字体的单位。在一个地方,我正在执行命中测试来检查用户是否在屏幕上某些文本的边界矩形内单击了。我需要为此使用类似MeasureString的东西。不幸的是,执行命中测试的代码深藏在无法访问Graphics对象或甚至是Control的库中。在不使用图形对象的情况下测量字符串?

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

+0

如果您没有控件,您有什么?我假设字体和字符串,但还有什么? – micahtan 2009-06-16 19:09:47

+0

没有别的。我的图书馆是一种场景图。我试图避免依赖于System.Drawing和System.Windows.Forms – 2009-06-17 04:29:34

回答

44

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

+2

TextRenderer的小问题是它使用整数作为返回值,如果您需要子像素精度,会导致问题。否则,这是一个很好的选择。 – 2010-09-01 03:45:14

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为好。

10

MeasureString在@NerdFury答案中的方法会给出比预期更高的字符串宽度。您可以找到here的附加信息。如果你想只测量物理长度,请添加此两行:

g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; 
result = 
    g.MeasureString(measuredString, font, int.MaxValue, StringFormat.GenericTypographic); 
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库。

0

这可能不是别人的重复,但我的问题是不需要的图形对象。听了上面的挫折后,我只是尝试:

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

(其中,“内容”是衡量和cardfont的字体是在字符串)

...并且是运气。我可以使用结果来设置VSTO中列的宽度。

相关问题