TextRenderer.MeasureText和Graphics.MeasureString的大小不匹配

这不是一个四舍五入的问题。 差异~5+像素。

测试用例字符串:“”MACD(26,12,9)-0.000016“

e.Graphics.MeasureString("MACD (26,12,9) -0.000016", SystemFonts.DefaultFont).Width) TextRenderer.MeasureText("MACD (26,12,9) -0.000016", SystemFonts.DefaultFont).Width) 

结果总是:

 139.3942 134 

为什么这么大的差异呢? 我只需要在外面绘制圆形宽度的方法。 但它应匹配MeasureString,反之亦然。

TextRenderer使用GDI渲染文本,而Graphics使用GDI +。 两者使用略有不同的方法来布局文本,因此尺寸不同。

您应该使用哪一个取决于最终用于实际绘制文本的内容。 如果您使用GDI + Graphics.DrawString绘制它,请使用Graphics.MeasureString测量。 如果使用GDI TextRenderer.DrawText进行绘制,请使用TextRenderer.DrawText测量。

如果文本将显示在Windows窗体控件中,则它将使用TextRenderer如果UseCompatibleTextRendering设置为false (这是默认值)。

在您的问题的行之间阅读,您似乎使用TextRenderer因为您没有Paint事件之外的Graphics实例。 如果是这种情况,您可以自己创建一个来进行测量:

 using( Graphics g = someControl.CreateGraphics() ) { SizeF size = g.MeasureString("some text", SystemFonts.DefaultFont); } 

如果您无权访问控件以创建图形实例,则可以使用此操作为屏幕创建一个控件,该工具可用于测量目的。

 using( Graphics g = Graphics.FromHwnd(IntPtr.Zero) ) { SizeF size = g.MeasureString("some text", SystemFonts.DefaultFont); } 

我在下面的类中使用了在paint事件之外的MeasureString,它运行得很好。

 public interface ITextMeasurer { SizeF MeasureString(string text, Font font, StringFormat format); } public class TextMeasurer : ITextMeasurer { private readonly Image _fakeImage; private readonly Graphics _graphics; public TextMeasurer() { _fakeImage = new Bitmap(1, 1); _graphics = Graphics.FromImage(_fakeImage); } public SizeF MeasureString(string text, Font font, StringFormat format) { return _graphics.MeasureString(text, font, int.MaxValue, format); } }