Graphics.DrawString()的中心文本输出

我正在使用.NETCF(Windows Mobile) Graphics类和DrawString()方法来呈现单个字符的屏幕。

问题是,我似乎无法正确地居中。 无论我为string渲染的位置的Y坐标设置什么,它总是低于此值,文本大小越大,Y偏移量越大。

例如,在文本大小为12时,偏移大约是4,但是在32处偏移大约是10。

我希望angular色垂直占据大部分正在绘制的矩形,并水平居中。 这是我的基本代码。 this是引用它被绘制的用户控件。

 Graphics g = this.CreateGraphics(); float padx = ((float)this.Size.Width) * (0.05F); float pady = ((float)this.Size.Height) * (0.05F); float width = ((float)this.Size.Width) - 2 * padx; float height = ((float)this.Size.Height) - 2 * pady; float emSize = height; g.DrawString(letter, new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular), new SolidBrush(Color.Black), padx, pady); 

是的,我知道有我可以使用的标签控件,并将其设置为居中,但实际上我需要使用Graphics类手动执行此操作。

我想为StringFormat对象添加另一个投票。 你可以简单地使用这个来指定“中心,中心”,文本将在矩形或点提供的中心绘制:

 StringFormat format = new StringFormat(); format.LineAlignment = StringAlignment.Center; format.Alignment = StringAlignment.Center; 

然而在CF中有这个问题。 如果您使用中心这两个值然后它closuresTextWrapping。 不知道为什么会发生这种情况,这似乎是与CF的错误。

要alignment文本,请使用以下内容:

 StringFormat sf = new StringFormat(); sf.LineAlignment = StringAlignment.Center; sf.Alignment = StringAlignment.Center; e.Graphics.DrawString("My String", this.Font, Brushes.Black, ClientRectangle, sf); 

请注意,这里的文本是在给定的范围内alignment。 在这个例子中,这是ClientRectangle。

通过结合我得到的build议,我想出了这个:

  private void DrawLetter() { Graphics g = this.CreateGraphics(); float width = ((float)this.ClientRectangle.Width); float height = ((float)this.ClientRectangle.Width); float emSize = height; Font font = new Font(FontFamily.GenericSansSerif, emSize, FontStyle.Regular); font = FindBestFitFont(g, letter.ToString(), font, this.ClientRectangle.Size); SizeF size = g.MeasureString(letter.ToString(), font); g.DrawString(letter, font, new SolidBrush(Color.Black), (width-size.Width)/2, 0); } private Font FindBestFitFont(Graphics g, String text, Font font, Size proposedSize) { // Compute actual size, shrink if needed while (true) { SizeF size = g.MeasureString(text, font); // It fits, back out if (size.Height <= proposedSize.Height && size.Width <= proposedSize.Width) { return font; } // Try a smaller font (90% of old size) Font oldFont = font; font = new Font(font.Name, (float)(font.Size * .9), font.Style); oldFont.Dispose(); } } 

到目前为止,这工作完美无瑕。

我唯一要做的就是将FindBestFitFont()调用移到OnResize()事件上,这样我就不会每次画一个字母就调用它。 只有在控件大小发生变化时才需要调用它。 我只是将它包含在函数中以获得完整性。

绘制居中的文字:

 TextRenderer.DrawText(g, "my text", Font, Bounds, ForeColor, BackColor, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter | TextFormatFlags.GlyphOverhangPadding); 

确定填充区域的最佳字体大小有点困难。 我发现的一个有效的尝试是试错法(trial-and-error):从一个大字体开始,然后重复测量string并缩小字体直到适合。

 Font FindBestFitFont(Graphics g, String text, Font font, Size proposedSize, TextFormatFlags flags) { // Compute actual size, shrink if needed while (true) { Size size = TextRenderer.MeasureText(g, text, font, proposedSize, flags); // It fits, back out if ( size.Height <= proposedSize.Height && size.Width <= proposedSize.Width) { return font; } // Try a smaller font (90% of old size) Font oldFont = font; font = new Font(font.FontFamily, (float)(font.Size * .9)); oldFont.Dispose(); } } 

你会用这个:

 Font bestFitFont = FindBestFitFont(g, text, someBigFont, sizeToFitIn, flags); // Then do your drawing using the bestFitFont // Don't forget to dispose the font (if/when needed) 

这是一些代码。 这假定您正在窗体或UserControl上执行此操作。

 Graphics g = this.CreateGraphics(); SizeF size = g.MeasureString("string to measure"); int nLeft = Convert.ToInt32((this.ClientRectangle.Width / 2) - (size.Width / 2)); int nTop = Convert.ToInt32((this.ClientRectangle.Height / 2) - (size.Height / 2)); 

从你的post来看,这听起来像ClientRectangle部分(如你不使用它)是什么给你的困难。

您可以使用传入DrawString方法的StringFormat对象的实例来居中文本。

请参阅Graphics.DrawString方法和StringFormat类 。

Interesting Posts