4

我在 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()方法,但我的“文本”使事情变得复杂,因为它可能包含分页符。

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

4

4 回答 4

9

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

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);
于 2010-04-07T15:26:09.173 回答
3

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

于 2010-04-07T15:22:48.790 回答
2

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

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);
于 2011-09-27T19:38:39.930 回答
1

我只是想添加(一年后)我创建的一个工具,因为StringAlignment结果证明它不是很可靠。事实证明,它与 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);
}

要将这些用于标签的 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。

〜乔

于 2012-08-03T13:50:22.473 回答