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); } }