2010-10-30 46 views
0

我有2个groupboxes,我想定制一些,我不想求助于具有标签的面板(这将意味着我会有如果我需要一个边框,则面板和父控件的背景颜色相同,因为标签必须设置颜色才能覆盖文字背后的边框)。C#Groupbox - 自定义边框/标题的外观和感觉

我已经设法捕捉油漆事件,并使用下面的代码更改边框颜色:

Graphics gfx = e.Graphics; 
Pen p = new Pen(Color.FromArgb(86, 136, 186), 3); 

GroupBox gb = (GroupBox)sender; 
Rectangle r = new Rectangle(0, 0, gb.Width, gb.Height); 

gfx.DrawLine(p, 0, 5, 0, r.Height - 2); 
gfx.DrawLine(p, 0, 5, 10, 5); 
gfx.DrawLine(p, 62, 5, r.Width - 2, 5); 
gfx.DrawLine(p, r.Width - 2, 5, r.Width - 2, r.Height - 2); 
gfx.DrawLine(p, r.Width - 2, r.Height - 2, 0, r.Height - 2); 

我的问题是,像这样的,如果标题太长那么重叠的边界。因为它与顶部的左侧边框重叠 - 只需调整第二行DrawLine即可轻松解决。不过,我想检测文本的x和宽度测量值,以便我可以正确定位边框。

有没有人有任何想法如何做到这一点?我在Google上看了一段时间,但没有发现任何内容。我知道标题是通过GroupBox.Text设置的。

也请说出是否有任何其他测量可能需要,基于我改变边框的粗细,所以如果字体很小但边界是10像素开始半边向下看起来很奇怪。 。

在此先感谢。

问候,

理查德

回答

2

很容易得到字符串的大小,因为我看到你已经发现了。但我认为控制的子类化会更容易,允许更好的外观为您提供设计时间支持。这里有一个例子:

public class GroupBoxEx : GroupBox 
{ 
    SizeF sizeOfText; 
    protected override void OnTextChanged(EventArgs e) 
    { 
     base.OnTextChanged(e); 
     CalculateTextSize();    
    } 

    protected override void OnFontChanged(EventArgs e) 
    { 
     base.OnFontChanged(e); 
     CalculateTextSize(); 
    } 

    protected void CalculateTextSize() 
    { 
     // measure the string: 
     using (Graphics g = this.CreateGraphics()) 
     { 
      sizeOfText = g.MeasureString(Text, Font); 
     } 
     linePen = new Pen(Color.FromArgb(86, 136, 186), sizeOfText.Height * 0.1F); 
    } 

    Pen linePen; 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     // Draw the string, we now have complete control over where: 

     Rectangle r = new Rectangle(ClientRectangle.Left + Margin.Left, 
      ClientRectangle.Top + Margin.Top, 
      ClientRectangle.Width - Margin.Left - Margin.Right, 
      ClientRectangle.Height - Margin.Top - Margin.Bottom); 

     const int gapInLine = 2; 
     const int textMarginLeft = 7, textMarginTop = 2; 

     // Top line: 
     e.Graphics.DrawLine(linePen, r.Left, r.Top, r.Left + textMarginLeft - gapInLine, r.Top); 
     e.Graphics.DrawLine(linePen, r.Left + textMarginLeft + sizeOfText.Width, r.Top, r.Right, r.Top); 
     // and so on... 

     // Now, draw the string at the desired location:    
     e.Graphics.DrawString(Text, Font, Brushes.Black, new Point(this.ClientRectangle.Left + textMarginLeft, this.ClientRectangle.Top - textMarginTop)); 
    } 
} 

你会发现,控制不画本身了,你负责的全过程。这可以让你确切地知道文本的绘制位置 - 你正在绘制它。

(另请注意,该行是字符串的高度的1/10。)

+0

感谢这应该工作一种享受! – ClarkeyBoy 2010-10-30 09:19:11

0

嗯,我现在已经找到了如何让一段文字的长度......我用下面的:

SizeF textsize = gfx.MeasureString(gb.Text, gb.Font); 

其中GFX图形是gb是GroupBox。不过,我认为这可能是值得的,只需编写自己的自定义类继承面板,添加一个标签,然后我将能够告诉它放置标签1,5,10,200,254等像素。甚至百分比。我还发现,我无法重写标准边框 - 它仍然通过我添加的边框显示,如果我的边框是1px - 使用GroupBox的另一个缺点。

问候,

理查德