2010-04-07 40 views
4

我已重寫我的Label控制在VS2008的OnPaint方法:圖形的DrawString以精確地放置在System.Label文本

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()方法,但我的「文本」使問題複雜化,因爲它可能包含分頁符。

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

回答

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

您可以撥打TextRenderer.DrawTextHorizontalCenterVerticalCenter標誌。

+1

您還必須使用帶'Rectangle'的重載。 – Aaronaught 2010-04-07 15:25:07

+0

TrueType提示很容易破壞陰影效果。 – 2010-04-07 15:34:45

+0

@SLaks:我將如何獲取System.Label對象的DeviceContext(第一個參數)? – jp2code 2010-04-07 15:48:14

9

或者你可以創建自己的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); 
+0

兩者都是答案,但我只能標記一個。這個有其他人跟進的代碼。 – jp2code 2010-04-07 20:55:24

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。

〜Joe

相關問題