views:

25

answers:

2

Hey,

I have 2 groupboxes which I would like to customise a bit more, and I dont want to resort to having a panel with a label (this would mean that I would have to have the same background colour for the panel and the parent control if I wanted a border, since the label would have to have a colour set to cover up the border behind the text).

I have managed to change the border colour by capturing the paint event and using the following code:

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

My problem is that, like this, if the caption is too long then it overlaps the border. As it is it overlaps the left hand border at the top - thats easy to solve simply by adjusting the 2nd DrawLine line. However I would like to detect the x and width measurements of the text so that I can position the borders properly.

Does anyone have any idea how to do this? I have looked on Google for a while but nothing jumps out at me. I know the caption is set through GroupBox.Text.

Please also say if there are any other measurements I may need, on the basis that I am changing the border thickness too so it would look odd if the font was tiny but the border was 10 pixels starting half way down...

Thanks in advance.

Regards,

Richard

A: 

Well I have now found out how to get the length of a piece of text... I used the following:

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

Where gfx is Graphics and gb is a GroupBox. However I think it may be worth just writing my own custom class which inherits from Panel, adding a label to it and then I will be able to tell it to place the label 1, 5, 10, 200, 254 etc pixels in. Or even a percentage in. I also found that I couldnt override the standard border - it still shows through the border I added if my border is 1px - another disadvantage to using GroupBox.

Regards,

Richard

ClarkeyBoy
+1  A: 

It's easy to get the size of the string, as I see you've found out. But I think that subclassing the control would be much easier, allow for a better look and give you design time support. Here is an example:

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

You'll notice that the control doesn't paint itself anymore, you're in charge of the whole process. This allows you to know exactly where the text gets drawn - you're drawing it yourself.

(Note also that the line is 1/10 of the height of the string.)

steinar
Thanks this should work a treat!
ClarkeyBoy