Click here to Skip to main content
6,634,665 members and growing! (16,927 online)
Email Password   helpLost your password?
Desktop Development » Static & Panel Controls » Custom Controls     Intermediate License: The Code Project Open License (CPOL)

A simple yet practical expandable group box for Windows Forms

By Josh Fischer

This expandable group box solves a screen design issue I have encountered often with multi-tab Windows Forms.
C#.NET 2.0, Dev
Version:2 (See All)
Posted:10 Oct 2008
Views:10,497
Bookmarked:21 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
9 votes for this article.
Popularity: 3.47 Rating: 3.63 out of 5
2 votes, 22.2%
1
1 vote, 11.1%
2

3
3 votes, 33.3%
4
3 votes, 33.3%
5

The Problem

I recently ran into a problem involving a multi-tab form using standard 2.0 WinForms. The first tab was full of data fields, leaving only the "notes" fields to be placed on the second tab. Conventional practices would have us use as much room as possible for the note text boxes since this allows the most text to be input and displayed. However, what you end up with is a very ugly tab that often conflicts with the layout style and color contrast on other tabs. To make matters worse, there is often little or no data in the text boxes so they are nothing but large white distractions.

TheProblem.jpg

The Solution

My solution was to create a simple expandable group box. The class extends the base GroupBox class so all the standard functionality is available. Each group box can have custom (design or runtime) expansion X and Y endpoints based on other controls on the form. Other things such as padding and the expansion images are also customizable from the designer.

PreExpand.jpg

PostExpand.jpg

Configuration

The control functions as expected "out of the box", and it is very easy to configure the expansion behavior. The screenshot below shows the custom properties that are displayed in Visual Studio.

Properties.jpg

PostExpand2.jpg

The Result

The result is a much cleaner interface that will not cause your users to cringe when they see it.

Final.jpg

Final2.jpg

The Code

The code is painfully simple, and basically boils down to one "toggle" method and a number of properties (not shown).

// Add the toggle image and react when it is clicked
public ExpandableGroupBox()
{
    InitializeComponent();

    TogglePicBox = new PictureBox();
    TogglePicBox.Size = new Size(16, 16);
    TogglePicBox.Image = ExpandPicture;
    TogglePicBox.Location = new Point(Width - 20, 0);
    TogglePicBox.Anchor = AnchorStyles.Top | AnchorStyles.Right;
    TogglePicBox.Click += new EventHandler(TogglePicBox_Click);
    Controls.Add(TogglePicBox);
}

private void TogglePicBox_Click(object sender, EventArgs e)
{
    ToggleExpansion();
}

protected void ToggleExpansion()
{
    // Set original size at runtime's first toggle
    // in case other size manipulation has taken place
    if (OriginalSize.Width == 0 && OriginalSize.Height == 0)
    {
        OriginalSize = Size;
    }

    Expanded = !Expanded;
    if (Expanded)
    {
        TogglePicBox.Image = CollapsePicture;

        // Determine whether a right boundary control was used and resize accordingly
        int newWidth = -1;
        if (HorizontalEndPoint != null)
        {
            newWidth = HorizontalEndPoint.Location.X - Location.X - Margin.Right;
        }
        else
        {
            newWidth = Parent.Size.Width - Location.X - Margin.Right - RightMargin;
        }

        if (newWidth < Width)
        {
            newWidth = Width;
        }

        // Determine whether a bottom boundary control was used and resize accordingly
        int newHeight = -1;
        if (VerticalEndPoint != null)
        {
            newHeight = VerticalEndPoint.Location.Y - Location.Y - Margin.Bottom;
        }
        else
        {
            newHeight = Parent.Size.Height - Location.Y - Margin.Bottom - BottomMargin;
        }

        if (newHeight < Height)
        {
            newHeight = Height;
        }

        Size = new Size(newWidth, newHeight);

        // Determine what anchors are needed
        if (AnchorRightOnExpand)
        {
            Anchor |= AnchorStyles.Right;
        }
        if (AnchorBottomOnExpand)
        {
            Anchor |= AnchorStyles.Bottom;
        }
    }
    else
    {
        // Reset
        TogglePicBox.Image = ExpandPicture;
        Size = OriginalSize;
        Anchor = AnchorStyles.Top | AnchorStyles.Left;
    }
}

protected PictureBox TogglePicBox
{
    get
    {
        return _togglePicBox;
    }
    set
    {
        _togglePicBox = value;
    }
}
private PictureBox _togglePicBox = null;

Points of Interest

Remember that once you drag the control onto your form, the default images are now stored in your project and can not be changed by replacing them in the control's project; your form will assume you set them yourself and override the pictures on the new build of the control. The same is true for the other public settings and for most custom controls, in general.

History

  • Version 1.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Josh Fischer


Member

Occupation: Software Developer (Senior)
Location: United States United States

Other popular Static & Panel Controls articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 1 of 1 (Total in Forum: 1) (Refresh)FirstPrevNext
GeneralNice... but... PinmemberIngenious HM21:21 14 Nov '08  

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

PermaLink | Privacy | Terms of Use
Last Updated: 10 Oct 2008
Editor: Smitha Vijayan
Copyright 2008 by Josh Fischer
Everything else Copyright © CodeProject, 1999-2009
Web17 | Advertise on the Code Project