问题
I have overridden the OnPaint method of my Label control 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 find out how to center the text both vertically and horizontally. I've heard of the MeasureString()
method, but my "Text" complicates matters because it could include page breaks.
Could someone guide me with how to do this?
回答1:
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:
Alternatively you can create your own StringFormat
object and pass it in using an overload of DrawString
that supports a 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);
回答3:
You can call TextRenderer.DrawText with the HorizontalCenter
and VerticalCenter
flags.
回答4:
I just wanted to add (a year later) a tool I created because StringAlignment
turned out to be not very dependable. It turns out to be very similar to Neo's version.
The code below does an excellent job of centering the text both vertically and horizontally. Also, I wrote it with various overloads so that different options could be supplied to make this control behave exactly like 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 these for the Label's OnPaint event, simply modify my original code in the question to following:
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 a Print_Document event, I have a version that will also print a box around the label if there is already a box around it in the designer:
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 at all useful, give me a +1.
~Joe
来源:https://stackoverflow.com/questions/2593675/graphics-drawstring-to-exactly-place-text-on-a-system-label