为什么DrawString在C#Winforms中表现出意想不到的行为?

Ko9*_*Ko9 6 c# controls drawstring onpaint winforms

我已经在C#WinForms中创建了一个控件,并且在我的OnPaint()处理程序中自定义绘图文本.使用我的表单中的以下代码将字体设置为Courier New:

FontFamily family = new FontFamily("Courier New");
this.myControl.Font = new Font(family, 10);
Run Code Online (Sandbox Code Playgroud)

在控件本身,字符串存储在realText,我使用以下代码将其绘制到屏幕:

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);

    e.Graphics.DrawString(realText, Font, new SolidBrush(ForeColor), ClientRectangle);
}
Run Code Online (Sandbox Code Playgroud)

一些随机示例文本的结果如下所示:http: //img219.imageshack.us/img219/1778/courier.png

如果你放大,你可以看到,例如,第一个'as'之间的空间不同于第二个'as'之间的空格(1个像素对2个像素).有没有人知道可能导致这种情况的原因,或者我如何防止它发生?我使用不同的字体绘制的间距有很多类似的怪异,但我认为它们都是同一问题的结果.

提前感谢您的任何想法.

Mik*_*ost 6

我猜这是因为你用的是Graphics.DrawString()代替TextRenderer.DrawText().前者使用GDI +绘制文本,这有点蹩脚和过时.后者使用更现代的GDI(在文本渲染方面).我相信这是前一个答案(WinForms vs. Windows)所指出的差异.

您也可以尝试Graphics.DrawString()使用StringFormat对象并指定的重载StringFormat.GenericTypographic.然而,这实际上是一个关于这个问题的黑客攻击.如果您使用的是.NET 2.0或更高版本,那么您应该使用TextRenderer类而不是蹩脚的Graphics类来满足所有文本呈现需求. Graphics.MeasureString()并且Graphics.DrawString()严格存在以便与.NET 1.0和1.1向后兼容.

编辑:哦是的,你的代码在每个绘制周期都会泄漏一个GDI对象.Brush对象是围绕非托管资源的托管包装器,因此必须明确处理它们.