Click here to Skip to main content
6,936,634 members and growing! (18,879 online)
Email Password   helpLost your password?
 
Desktop Development » Miscellaneous » Miscellaneous Controls     Intermediate

XP Style Collapsible GroupBox

By jordanhammond

This article describes an XP style collapsible GroupBox.
C#, Windows, .NET2.0, GDI+, WinForms, VS2005, Dev
Posted:26 Jan 2006
Updated:31 Jan 2006
Views:82,732
Bookmarked:133 times
printPrint Friendly   add Share
      Discuss Discuss   Broken Article?Report  
24 votes for this article.
Popularity: 6.34 Rating: 4.60 out of 5
1 vote, 4.2%
1

2
1 vote, 4.2%
3
6 votes, 25.0%
4
16 votes, 66.7%
5

Sample Image

Introduction

Sometimes, there is the need to display information in a container that can be collapsed. Sure there are controls like the XP Sidebar et all, but for my requirements, I wanted something that looked and worked exactly like a standard GroupBox. So, I simply extended the GroupBox control to provide this functionality.

Background

I searched the web for existing controls and came across one by jeffb42 which was pretty much what I wanted, however I have been developing in .NET 2.0 only for some time now, and the old format design did not sit well with the normal GroupBoxes on my forms. Also, that version did not allow me to easily add other controls to the box for some reason. So, I created my own based on the one by jeffb42.

Using the code

This control is so simple that it barely warrants instructions. It can be used as a normal GroupBox is. Full design time support is provided so simply drag & drop the control onto your form and add what you wish to it.

Behind the control

Looking through the code, one can see that not much was required to create this control. The usual suspects were overridden to control the paint and the handling of the mouse clicking the Collapsed state toggle button.

protected override void OnMouseUp(MouseEventArgs e)
{
    if (m_toggleRect.Contains(e.Location))
        ToggleCollapsed();
    else
        base.OnMouseUp(e);
}

protected override void OnPaint(PaintEventArgs e)
{
    HandleResize();
    DrawGroupBox(e.Graphics);
    DrawToggleButton(e.Graphics);
}

For the painting, I used a method found in System.Windows.Forms called DrawGroupBox. This takes away all need to draw arcs and lines or worry about matching the colour of the normal GroupBox. However, when the GroupBox text is drawn on this box, you will get a strikeout effect. To overcome this, I draw a line the same length as the measured text in the colour of the control so that it will not be seen.

void DrawGroupBox(Graphics g)
{
    // Get windows to draw the GroupBox

    Rectangle bounds = new Rectangle(ClientRectangle.X, 
       ClientRectangle.Y + 6, ClientRectangle.Width, 
       ClientRectangle.Height - 6);
    GroupBoxRenderer.DrawGroupBox(g, bounds, Enabled ? 
       GroupBoxState.Normal : GroupBoxState.Disabled);

    // Text Formating positioning & Size

    StringFormat sf = new StringFormat();
    int i_textPos = (bounds.X + 8) + m_toggleRect.Width + 2;
    int i_textSize = (int)g.MeasureString(Text, this.Font).Width;
    i_textSize = i_textSize < 1 ? 1 : i_textSize;
    int i_endPos = i_textPos + i_textSize + 1;

    // Draw a line to cover the GroupBox

    // border where the text will sit

    g.DrawLine(SystemPens.Control, i_textPos, 
               bounds.Y, i_endPos, bounds.Y);

    // Draw the GroupBox text

    using (SolidBrush drawBrush = new 
               SolidBrush(Color.FromArgb(0, 70, 213)))
        g.DrawString(Text, this.Font, drawBrush, i_textPos, 0);
}

void DrawToggleButton(Graphics g)
{
    if(IsCollapsed)
        g.DrawImage(Properties.Resources.plus, m_toggleRect);
    else
        g.DrawImage(Properties.Resources.minus, m_toggleRect);
}

Points of Interest

If you are using this control in a DockStyle state of Fill then you will notice the control does not collapse. This is because the parent control forces the control to fill its space. Therefore, there is an event on the control which fires when the collapsed state changes. This can be used by the parent control to resize itself to the size of the GroupBox.

History

OK, after a request for a 1.1 version of this control, I thought I would give it a shot. After not using Visual Studio 2003 for around a year, it was a shock to switch back to it. Now, a lot of the methods that I used in the 2.0 solution were not available in 1.1, especially drawing a rounded rectangle. Rather than calculating all the points and curves myself, I looked through CodeProject because surely someone had done it before. And of course someone has, Arun Reginald's article provided a simple solution.

The rest is pretty much the same as in the 2.0 solution. I used Barretto VN's idea to add XP theming to all the controls used in the project.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

jordanhammond


Member
I write code.
Occupation: Web Developer
Location: United Kingdom United Kingdom

Other popular Miscellaneous articles:

 
Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 25 of 56 (Total in Forum: 56) (Refresh)FirstPrevNext
GeneralBroken link PinmemberWolexie5:48 22 Jan '10  
QuestionGreat Control but is there a way to disable or hide border Pinmemberbokee118:12 27 Oct '09  
AnswerRe: Great Control but is there a way to disable or hide border Pinmemberbokee1110:21 27 Oct '09  
GeneralSome minor changes... PinmemberGMan49118:27 4 Oct '09  
GeneralRe: Some minor changes... PinmemberDominikF2:19 8 Dec '09  
QuestionCode Usage - Article Pinmemberstixoffire6:51 18 May '09  
GeneralLicense PinmemberAlmagnus114:40 3 Mar '09  
GeneralInvisible controls Pinmemberpl_meetom4:09 8 Dec '08  
GeneralThe test program crashes if you run it with the "Windows Classic" theme on XP [modified] Pinmemberbscaer6:38 10 Jun '08  
GeneralResize parents [modified] Pinmemberesskar3:52 17 Sep '07  
QuestionRe: Resize parents [modified] Pinmemberstixoffire10:08 10 Jun '08  
AnswerRe: Resize parents Pinmembertretererte8:37 29 Oct '09  
GeneralI like it, small bug (small small) [modified] Pinmemberbilo813:28 4 May '07  
GeneralRe: I like it, small bug (small small) PinmemberRoss Korsky7:22 6 Jun '08  
GeneralRe: I like it, small bug (small small) Pinmembermaynardflies5:28 15 Aug '08  
NewsDesign-time enhancement PinmembercDima3:48 17 Apr '07  
Hey, nice control.

I've got an improvement for it. By adding a class and some attributes, you can enable design-time collapsing of the group box by a mouse click on the box. It will save the size of the non-collapsed group box and all.

It will probably work only for VS 2005 .Net 2.0, haven't checked.

I can make a short article with the implemented details and post it on code project. Or, if you have the time, update the control with these improvements, if you think they actually improve it.

Quite simple. Add a reference to System.Design.dll in your project.
Then add the CollapsibleGroupBoxDesigner class:

    /// 
    /// CollapsibleGroupBoxDesigner is an control designer for the that 
/// CollapsibleGroupBox. Allows mouse clicks on the collapse button.
/// summary
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
public class CollapsibleGroupBoxDesigner : System.Windows.Forms.Design.ParentControlDesigner
{
// This boolean state reflects whether the mouse is over the control.
protected override bool GetHitTest(Point point)
{
CollapsibleGroupBox me = this.Control as CollapsibleGroupBox;

if (me.m_toggleRect.Contains(me.PointToClient(point)))
{
// we can handle that; user clicked on toggle box.
return true;
}
//Nope not interested
return false;
}
}

Then, add the DesignerAttribute atttribute in front of the class itself. Also, you'll need to make the property toggleRect public.

    /// 
    /// GroupBox control that provides functionality to 
/// allow it to be collapsed.
/// summary
[ToolboxBitmap(typeof(CollapsibleGroupBox))]
[DesignerAttribute(typeof(CollapsibleGroupBoxDesigner))]
public partial class CollapsibleGroupBox : GroupBox
{

....
public Rectangle m_toggleRect = new Rectangle(8, 2, 11, 11); // not private
....

/// summary
/// Save the size if control is collapsed. VS will serialize the attribute for us.
/// It is also shown in properties.
/// summary
[DefaultValue(false), Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Size FullSize
{
get
{
return m_FullSize;
}
set
{
m_FullSize = value;
}
}

That's probably all, if I'm not missing anything.
Now recompile the project, drop the collapsable group box control on a form in the designer, and click on the toggle box. It should toggle collapse and save it's original size in it's FullSize property.

Works for me quite nicely. Get back to me if you will update the control, please.

Good luck,
Dmitry Sadakov
GeneralRe: Design-time enhancement Pinmemberstixoffire10:10 10 Jun '08  
QuestionRe: Design-time enhancement Pinmemberstixoffire1:28 18 Apr '09  
GeneralLocalization messes up the control PinmemberBo K8:12 8 Feb '07  
GeneralCollapse box look PinmemberE! Ray K9:52 29 Jan '07  
QuestionFor some reason.. Pinmemberadvance5128:07 31 Aug '06  
GeneralCustomize colors PinmemberRogenator_202414:35 15 Jul '06  
GeneralGreat Component! PinmemberMikeNutshell14:06 16 Jun '06  
GeneralRe: Great Component! PinmemberRogenator_202415:40 11 Jul '06  
GeneralRight to left PinmemberAhmad Maatouki0:44 2 Apr '06  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+PgUp/PgDown to switch pages.

PermaLink | Privacy | Terms of Use
Last Updated: 31 Jan 2006
Editor: Smitha Vijayan
Copyright 2006 by jordanhammond
Everything else Copyright © CodeProject, 1999-2010
Web18 | Advertise on the Code Project