本文转自http://www.codeproject.com/KB/miscctrl/CollapsibleGroupBox.aspx
I am working on a project that needs to display groups/containers of editable data (data not just for display), and I came up with the idea for this library of controls. I looked into using a PropertyGrid
control but it didn't have the elegance I was looking for, so here are the fruits of my labor.
Years ago, I worked on a project for the Macintosh using Symantec's TCL (Think Class Library, not Tcl/Tk). TCL has a view and pane architecture where one would create a pane containing controls (or anything for that matter) and add the panes to a CScroller
. While searching CodeProject for something suitable, I came across Rollup Control and 3D Studio Max like Slidable DialogBar, but both are written in C++/MFC, and my project is in C#.
After opening your C# Windows Application solution, open a Form, right-click in the Toolbox, and select the "Add/Remove Items..." menu item. After the "Customize Toolbox" dialog comes up, select the "Browse..." button, and navigate to the \CollapsibleGroupBox_1_2\bin\Release directory, and select UIToolbox.dll. If you navigate to the "My User Controls" group in the Toolbox, you will notice that several items have been added.
Go back to the Solution Explorer, right-click on your project, and select the menu item Add\Add New Item. Select a user control and edit its code. Change the base class from System.Windows.Forms
to UIToolbox.CollapsibleGroupBox
, save it, and then switch back to its design view.
At this point, you should see something that looks like the following:
Feel free to resize it and add some controls.
Go back to the form you wish to add an ExpandingPanel
to (in the design view), and add an ExpandingPanel
(from the "My User Controls" group of the Toolbox), and you should see something like this:
Switch to the form's code and add supporting code to add the CollapsibleGroupBox
to the ExpandingPanel
:
public Form1()
{
//
// Required for Windows Form Designer support //
InitializeComponent();
// UserControl1 is a CollapsibleGroupBox expandingPanel1.AddGroup(new UserControl1());
}
That's it. You're ready to build and run it now. The controls automatically take care of collapsing, expanding, deleting themselves, and scrolling.
If you explore CollapsibleGroupBox.cs, you will notice that although it contains a control for the collapse button and a control for the trash can button, it doesn't contain a GroupBox
control. Instead, it 'fakes' a group box and draws it itself. Why? The first draft used a GroupBox
control, and everything seemed to work fine. That is, until I created a panel derived from ExpandingPanel
, added some controls, and then built it. When the project was built, the derived panel seemed to 'eat' the controls. It turns out that the bug had to do with the embedded group box and the ownership of the controls, so now the CollapsibleGroupBox
draws the group box itself.
Graphics.MeasureString()
to get the width, and I've noticed MeasureString()
doesn't always work correctly.ExpandingPanel
s and CollapsibleGroupBox
es are sometimes missing - If a form contains an ExpandingPanel
or CollapsibleGroupBox
control, I've noticed that sometimes they disappear the next time I open the project. A workaround that I've found that usually works is to close the form (both designer and code) and then reopen it. I haven't figured out why, but this seems to fix the problem.Caption
and ContainsTrashCan
properties of a CollapsibleGroupBox
, I've noticed that the trash can icon doesn't always appear in the correct position. Usually building the project solves this. Here are some potential enhancements I may make in the future:
Drag & Drop: It would be cool if ExpandingPanel
supported drag and drop and allowed you to d&d within an ExpandingPanel
to resort its items, or d&d to move a CollapsibleGroupBox
from one ExpandingPanel
to another. The UI would look something like this:
Add panes instead of CollapsibleGroupBox
es: For my project, I only needed group boxes, but for a more general purpose, I might change ExpandingPanel
to add a more generic type (Pane?):
public class Pane : System.Windows.Forms.UserControl
{
.
.
.
}
public class CollapsibleGroupBox : Pane
{
.
.
.
}
public class ExpandingPanel : System.Windows.Forms.Panel
{
.
.
.
public void AddGroup(UIToolbox.Pane thePane)
{
.
.
.
}
.
.
.
}
You may use and modify the original code to your needs, free of charge, provided:
You may not:
GroupBox
to a collapsed state.