C# Graphics.DrawString() 的中心文本输出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Center text output from Graphics.DrawString()
提问by Adam Haile
I'm using the .NETCF (Windows Mobile) Graphics
class and the DrawString()
method to render a single character to the screen.
我正在使用 .NETCF (Windows Mobile)Graphics
类和将DrawString()
单个字符呈现到屏幕的方法。
The problem is that I can't seem to get it centred properly. No matter what I set for the Y coordinate of the location of the string render, it always comes out lower than that and the larger the text size the greater the Y offset.
问题是我似乎无法正确居中。无论我为字符串渲染位置的 Y 坐标设置了什么,它总是低于该值,并且文本大小越大,Y 偏移量越大。
For example, at text size 12, the offset is about 4, but at 32 the offset is about 10.
例如,文本大小为 12 时,偏移量约为 4,但文本大小为 32 时,偏移量约为 10。
I want the character to vertically take up most of the rectangle it's being drawn in and be centred horizontally. Here's my basic code. this
is referencing the user control it's being drawn in.
我希望角色垂直占据绘制它的矩形的大部分并水平居中。这是我的基本代码。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);
Yes, I know there is the label control that I could use instead and set the centring with that, but I actually do need to do this manually with the Graphics
class.
是的,我知道有我可以使用的标签控件并以此设置居中,但实际上我确实需要在Graphics
类中手动执行此操作。
采纳答案by Adam Haile
Through a combination of the suggestions I got, I came up with this:
通过结合我得到的建议,我想出了这个:
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();
}
}
So far, this works flawlessly.
到目前为止,这完美无缺。
The only thing I would change is to move the FindBestFitFont() call to the OnResize() event so that I'm not calling it every time I draw a letter. It only needs to be called when the control size changes. I just included it in the function for completeness.
我唯一要改变的是将 FindBestFitFont() 调用移动到 OnResize() 事件,这样我就不会在每次绘制字母时都调用它。只有在控件大小发生变化时才需要调用它。为了完整性,我只是将它包含在函数中。
回答by John
You can use an instance of the StringFormat
object passed into the DrawString
method to center the text.
您可以使用StringFormat
传递给DrawString
方法的对象实例来使文本居中。
回答by TheSmurf
Here's some code. This assumes you are doing this on a form, or a UserControl.
这是一些代码。这假设您是在表单或 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));
From your post, it sounds like the ClientRectangle part (as in, you're not using it) is what's giving you difficulty.
从您的帖子中,听起来 ClientRectangle 部分(如您没有使用它)是给您带来困难的原因。
回答by dbkk
To draw a centered text:
要绘制居中文本:
TextRenderer.DrawText(g, "my text", Font, Bounds, ForeColor, BackColor,
TextFormatFlags.HorizontalCenter |
TextFormatFlags.VerticalCenter |
TextFormatFlags.GlyphOverhangPadding);
Determining optimal font size to fill an area is a bit more difficult. One working soultion I found is trial-and-error: start with a big font, then repeatedly measure the string and shrink the font until it fits.
确定填充区域的最佳字体大小有点困难。我发现一个可行的解决方案是反复试验:从一个大字体开始,然后反复测量字符串并缩小字体直到它适合。
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();
}
}
You'd use this as:
您可以将其用作:
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)
回答by Quibblesome
I'd like to add another vote for the StringFormat object. You can use this simply to specify "center, center" and the text will be drawn centrally in the rectangle or points provided:
我想为 StringFormat 对象再投一票。您可以简单地使用它来指定“中心,中心”,文本将在提供的矩形或点中居中绘制:
StringFormat format = new StringFormat();
format.LineAlignment = StringAlignment.Center;
format.Alignment = StringAlignment.Center;
However there is one issue with this in CF. If you use Center for both values then it turns TextWrapping off. No idea why this happens, it appears to be a bug with the CF.
然而,这在 CF 中存在一个问题。如果对这两个值都使用 Center,则会关闭 TextWrapping。不知道为什么会发生这种情况,这似乎是 CF 的一个错误。
回答by Chris Hughes
To align a text use the following:
要对齐文本,请使用以下命令:
StringFormat sf = new StringFormat();
sf.LineAlignment = StringAlignment.Center;
sf.Alignment = StringAlignment.Center;
e.Graphics.DrawString("My String", this.Font, Brushes.Black, ClientRectangle, sf);
Please note that the text here is aligned in the given bounds. In this sample this is the ClientRectangle.
请注意,此处的文本在给定的边界内对齐。在此示例中,这是 ClientRectangle。