图形DrawString将文本正确放置在System.Label上

我在VS2008中重写了我的Label控件的OnPaint方法:

void Label_OnPaint(object sender, PaintEventArgs e) { base.OnPaint(e); dim lbl = sender as Label; if (lbl != null) { string Text = lbl.Text; e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; if (myShowShadow) { // draw the shadow first! e.Graphics.DrawString(Text, lbl.Font, new SolidBrush(myShadowColor), myShadowOffset, StringFormat.GenericDefault); } e.Graphics.DrawString(Text, lbl.Font, new SolidBrush(lbl.ForeColor), 0, 0, StringFormat.GenericDefault); } } 

这是有效的,但我真的想知道如何垂直和水平居中文本。 我听说过MeasureString()方法,但我的“文本”使问题变得复杂,因为它可能包含分页符。

有人可以指导我如何做到这一点?

这是我目前正在使用的代码,

 SizeF size; string text = "Text goes here"; size = e.Graphics.MeasureString(text, font); x = (lineWidth / 2) - (size.Width / 2); y = top; e.Graphics.DrawString(text, font, Brushes.Black, x, y); 

或者,您可以创建自己的StringFormat对象,并使用支持RectangleF的DrawString重载传递它:

 StringFormat formatter = new StringFormat(); formatter.LineAlignment = StringAlignment.Center; formatter.Alignment = StringAlignment.Center; RectangleF rectangle = new RectangleF(0, 0, lbl.Width, lbl.Height); e.Graphics.DrawString(Text, lbl.Font, new SolidBrush(lbl.ForeColor), rectangle, formatter); 

您可以使用HorizontalCenterVerticalCenter标志调用TextRenderer.DrawText

我只想添加(一年后)我创建的工具,因为StringAlignment结果不是很可靠。 事实certificate它与Neo的版本非常相似。

下面的代码可以很好地垂直和水平对齐文本。 此外,我用各种重载编写它,以便可以提供不同的选项,使这个控件的行为完全像我想要的那样。

这是我的重载:

 private static void DrawCenter(Label label, Graphics graphics) { DrawCenter(label.Text, label, label.Location, label.ForeColor, graphics); } private void DrawCenter(string text, Label label, Graphics graphics) { DrawCenter(text, label, label.Location, label.ForeColor, graphics); } private static void DrawCenter(string text, Label label, Point location, Graphics graphics) { DrawCenter(text, label, location, label.ForeColor, graphics); } private static void DrawCenter(string text, Label label, Point location, Color fontColor, Graphics graphics) { Rectangle rect = new Rectangle(location, label.Size); SizeF lSize = graphics.MeasureString(text, label.Font, rect.Width); PointF lPoint = new PointF(rect.X + (rect.Width - lSize.Width) / 2, rect.Y + (rect.Height - lSize.Height) / 2); graphics.DrawString(text, label.Font, new SolidBrush(fontColor), lPoint); } 

要将这些用于Label的OnPaint事件,只需将问题中的原始代码修改为以下内容:

 private void Label_OnPaint(object sender, PaintEventArgs e) { base.OnPaint(e); Label lbl = sender as Label; if (lbl != null) { string txt = lbl.Text; e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; if (myShowShadow) { // draw the shadow first! Point offset = new Point(lbl.Location.X - 1, lbl.Location.Y - 1) DrawCenter(txt, lbl, offset, myShadowColor, e.Graphics); } DrawCenter(lbl, e.Graphics); } } 

对于Print_Document事件,我有一个版本,如果设计器中已经有一个框,它还会在标签周围打印一个框:

 private static void DrawCenter(string text, Label label, Point location, Color fontColor, Graphics graphics) { Rectangle rect = new Rectangle(location, label.Size); SizeF lSize = graphics.MeasureString(text, label.Font, rect.Width); PointF lPoint = new PointF((rect.Width - lSize.Width) / 2, (rect.Height - lSize.Height) / 2); graphics.DrawString(text, label.Font, new SolidBrush(fontColor), lPoint); if (label.BorderStyle != BorderStyle.None) { using (Pen p = new Pen(Color.Black)) { graphics.DrawRectangle(p, rect); } } } 

如果您觉得这很有用,请给我一个+1。

〜乔