Phil Wright : Component Factory

Friday, June 17, 2005

.NET2, Creating a GroupBox

Traditional GroupBox

The first control we need to create for our Navigator project is very similar to the traditional GroupBox that comes with the framework. Just like that control we need ours to draw a border around the control area and allow any contained controls to be positioned inside that border.

Here we can see the traditional GroupBox control with a single Button positioned inside it.

Positioning child controls

One of the great features introduced by version 1 of the framework is the Dock property. If the developer decides to assign DockStyle.Fill to the button then it will automatically size to fill the available area, like this.

This is useful because whenever the GroupBox is resized the Button willl automatically be resized to fill the available space. Unfortunately in version 1 of the framework there is no property that can be modified to inform the control to layout child controls within a particular area. So I was expecting to have to write a fair amount of code to get around this seemingly simple requirement.

I was going to get around the problem by creating a child Panel in the correct area and then letting the user design onto that panel instance. That way any Dock property settings they use would be effective against the panel and not the whole custom control.

.NET 2 Comes to the rescue

Luckily for us it seems the Microsoft developers realized this difficulty and have introduced a new property called DisplayRectangle in version 2 of the framework. This property returns the rectangle that should be used to layout the child controls within the control.

So all we need to do is override this virtual public property. There is one small complication that needs to be remembered though. Another new property introduced in version 2 of the framework is called Padding. This defines how far to inset the child controls when they are layed out. We need to make sure that our override honors this property.

So we end up with some code like the following in order to provide a 10 pixel border on all except the top edge that is given 20 pixels.

public override Rectangle DisplayRectangle
// Grab the total client size
Size s = ClientSize;

// Find the control defined padding
Padding p = Padding;

// Return the display rectangle
return new Padding(p.Left + 10,
p.Top + 20,
s.Width - p.Horizontal - 20,
s.Height - p.Vertical - 30);

This is one of things I love about the .NET framework, I often find that when I want to solve a problem the designer have already package up a nice simple solution for me!


Post a Comment

<< Home