簡體   English   中英

圖形DrawString將文本正確放置在System.Label上

[英]Graphics DrawString to Exactly Place Text on a 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()方法,但是我的“文本”使問題變得復雜,因為它可能包含分頁符。

有人可以指導我如何做到這一點?

或者,您可以創建自己的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

這是我目前正在使用的代碼,

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);

我只想添加(一年后)我創建的工具,因為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);
}

要將這些用於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。

〜喬

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM