DrawString Graphics to precisely place text on System.Label

I redefined the OnPaint method of my Label in VS2008:

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

This works, but I really want to learn how to center the text both vertically and horizontally. I heard about the MeasureString() method, but my β€œText” complicates the questions as it may include page breaks.

Can someone help me how to do this?

+4
source share
4 answers

Here is the code I'm using at the moment,

 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); 
+2
source

Alternatively, you can create your own StringFormat object and pass it using the DrawString overload, which supports 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); 
+9
source

You can call TextRenderer.DrawText with the HorizontalCenter and VerticalCenter flags.

+3
source

I just wanted to add (in a year) the tool that I created, because StringAlignment was not very reliable. This is very similar to the version of Neo.

The code below does an excellent job of centering the text vertically and horizontally. In addition, I wrote it with various overloads so that it would be possible to provide various parameters so that this control behaves the way I want.

Here are my overloads:

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

To use them for the Label OnPaint event, simply change the source code in the question as follows:

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

For the Print_Document event, I have a version that will also print a field around the label if the design already has a field:

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

If you find this helpful at all, give me +1.

~ Joe

+1
source

Source: https://habr.com/ru/post/1306258/


All Articles