Title: Use Windows Forms controls to make an expander in C#
WPF, Silverlight, Metro, or whatever Microsoft is calling this stuff now days has some useful controls in the System.Windows.Controls namespace including Expander. An Expander displays a small arrow button and a panel where you can place other controls. When the user clicks the arrow button, the control expands or collapses the panel. This lets you make a lot of information available to the user while allowing the user to show or hide information as desired.
This example shows how to build a simple expander in Windows Forms applications. The program's form contains a Button and a Panel that holds several Label, TextBox, and ComboBox controls.
The example's basic strategy is to use two timers to expand or collapse a Panel that contains other controls. The Panel control's MaximumSize and MinimumSize properties determine how much it can be expanded or collapsed.
When the user clicks the expand/collapse button the following code executes.
// The expander's current state.
private bool Expanded = false;
// Start expanding.
private void btnExpander_Click(object sender, EventArgs e)
{
if (Expanded)
{
btnExpander.Image = Properties.Resources.expander_down;
tmrCollapse.Enabled = true;
tmrExpand.Enabled = false;
}
else
{
btnExpander.Image = Properties.Resources.expander_up;
tmrExpand.Enabled = true;
tmrCollapse.Enabled = false;
}
Expanded = !Expanded;
}
The Expanded variable indicates whether the Panel is currently expanded. The button's event handler checks this variable to decide whether it should start expanding or collapsing the Panel. If the Panel is currently expanded, the code starts collapsing it. It sets the button's image to show the down (collapse) picture. It disables the collapse timer and enables the expand timer.
The code handles the case when the Panel is currently collapsed similarly, changing the button image, enabling the expand timer, and disabling the collapse timer.
The following code show the expand timer's Tick event handler.
// The number of pixels expanded per timer Tick.
private const int ExpansionPerTick = 7;
// Make the expander panel bigger.
private void tmrExpand_Tick(object sender, EventArgs e)
{
int new_height = panAddress.Height + ExpansionPerTick;
if (new_height >= panAddress.MaximumSize.Height)
{
tmrExpand.Enabled = false;
new_height = panAddress.MaximumSize.Height;
}
panAddress.Height = new_height;
}
The constant ExpansionPerTick gives the number of pixels that the Panel should be expanded or collapsed per timer Tick. I set the Timer components' Interval properties to 10 milliseconds and ExpansionPerTick to 7 so the Panel expands/collapses at a rate of 700 pixels per second. In practice this seems to be about as many ticks per second my computer can handle, so I picked a value that seemed reasonable for ExpansionPerTick.
When the expand timer's Tick event fires, it calculates the panel's new height. If this height is greater than or equal to the Panel control's maximum allowed height, the code disables the timer and sets the new height to the maximum allowed height.
The following code shows the collapse timer's Tick event handler.
// Make the expander panel smaller.
private void tmrCollapse_Tick(object sender, EventArgs e)
{
int new_height = panAddress.Height - ExpansionPerTick;
if (new_height <= panAddress.MinimumSize.Height)
{
tmrCollapse.Enabled = false;
new_height = panAddress.MinimumSize.Height;
}
panAddress.Height = new_height;
}
This code is similar to the previous code except it collapses the Panel instead of expanding it. You can compare the two Tick event handlers to see what's different.
My next post will describe an even more useful example that shows how to stack multiple expanders on top of each other.
Download the example to experiment with it and to see additional details.
|