C# 为什么TextRenderer在测量文本时添加边距?

C# 为什么TextRenderer在测量文本时添加边距?,c#,winforms,textrenderer,C#,Winforms,Textrenderer,由于我的应用程序中某些地方缺少图形对象,我决定使用TextRenderer类。但令人惊讶的是,它为测量文本增加了大量的边距。例如: private void button1_Click(object sender, EventArgs e) { using (var g = this.CreateGraphics()) { Font font = new Font("Calibri", 20.0f, GraphicsUnit.Pixel); Size

由于我的应用程序中某些地方缺少图形对象,我决定使用TextRenderer类。但令人惊讶的是,它为测量文本增加了大量的边距。例如:

private void button1_Click(object sender, EventArgs e) {

    using (var g = this.CreateGraphics()) {

        Font font = new Font("Calibri", 20.0f, GraphicsUnit.Pixel);
        Size size = TextRenderer.MeasureText("Ala ma kota", font);

        g.DrawRectangle(Pens.Red, new Rectangle(new Point(10, 10), size));
        TextRenderer.DrawText(g, "Ala ma kota", font, new Point(10, 10), Color.Black);
    }
}
给出以下结果:

为什么会这样?有没有办法强迫它获得真实的文本大小?(当然,在返回的同一个矩形中绘制)

来自:

例如,的默认行为是向绘制文本的边框添加填充,以适应悬垂图示符。如果需要在没有这些额外空格的情况下绘制一行文本,请使用采用and参数的and版本,如示例所示

您还必须传递
Graphics
对象才能获得正确的结果,因为:

MeasureText(字符串、字体、大小、TextFormatFlags)
的重载将忽略或的值。如果指定的填充值不是默认值,则应使用获取对象的重载

还可以直接使用
图形
方法:

来自:

例如,的默认行为是向绘制文本的边框添加填充,以适应悬垂图示符。如果需要在没有这些额外空格的情况下绘制一行文本,请使用采用and参数的and版本,如示例所示

您还必须传递
Graphics
对象才能获得正确的结果,因为:

MeasureText(字符串、字体、大小、TextFormatFlags)
的重载将忽略或的值。如果指定的填充值不是默认值,则应使用获取对象的重载


另外,请看一下如何直接使用
Graphics
方法:

您可以尝试在代码中添加一个TextFormatFlags枚举,正如您所看到的,您可以尝试在代码中添加一个TextFormatFlags枚举,正如您所看到的+1,该枚举删除了额外的填充。但是在我进行测量的地方,我没有
图形
对象:(@Spook很遗憾,这不起作用。我在MSDN的注释中进行了编辑。但是,您可以提供自己的
idevicontext
实现,该实现将返回例如屏幕
hDC
,这样您就不需要
图形
。不好:(看来我必须改变我项目的架构,这样图形对象就可以在那里使用了…@Spook你是说不允许创建图形对象,还是仅仅实现一个IDeviceContext就太多了?如果是后者,这似乎是可行的:使用(var g=FromHwnd(IntPtr.Zero)){var size=MeasureText(g,s,f,Size.Empty,TextFormatFlags.NoPadding);}(不确定Intptr.Zero(screen)是否在每台机器上都能工作,在过去,我使用了一个虚拟静态位图并从中创建了一个图形对象)@Me.Name它可能会工作,但有一个陷阱。因为(AFAIR)Windows 8,不同的窗口可能有不同的DPI设置-在这种情况下,如果窗口和桌面的DPI不同,我可能会得到无效的度量值。+1,这会删除额外的填充。但在我进行测量的地方,我没有
图形
对象:(@Spook很遗憾,这不起作用。我在MSDN的注释中进行了编辑。但是,您可以提供自己的
idevicontext
实现,该实现将返回例如屏幕
hDC
,这样您就不需要
图形
。不好:(看来我必须改变我项目的架构,这样图形对象就可以在那里使用了…@Spook你是说不允许创建图形对象,还是仅仅实现一个IDeviceContext就太多了?如果是后者,这似乎是可行的:使用(var g=FromHwnd(IntPtr.Zero)){var size=MeasureText(g,s,f,Size.Empty,TextFormatFlags.NoPadding);}(不确定Intptr.Zero(screen)是否在每台机器上都能工作,在过去,我使用了一个虚拟静态位图并从中创建了一个图形对象)@Me.Name它可能会工作,但有一个陷阱。因为(AFAIR)Windows 8,不同的窗口可能有不同的DPI设置-在这种情况下,如果窗口和桌面的DPI不同,我可能会得到无效的指标。
Size size = TextRenderer.MeasureText(g,
                                     "Ala ma kota",
                                     font,
                                     new Size(int.MaxValue, int.MaxValue),
                                     TextFormatFlags.NoPadding);

TextRenderer.DrawText(g, "Ala ma kota", font,
                      new Point(10, 10),
                      Color.Black,
                      TextFormatFlags.NoPadding);

g.DrawRectangle(Pens.Red, new Rectangle(new Point(10, 10), size));