Reusable Collapsible Panel for Web






4.61/5 (18 votes)
Jun 30, 2003
3 min read

174127

2883
A reusable collapsible panel user control for web applications
Introduction
This is a reusable Collapsible Panel user-control for web applications.
Background
Often we encounter web pages that run very long and it becomes difficult for the user to navigate down, dragging his mouse along all the way. So, when we want to display all the stuff on the same page and still keep it easy for the user, we could group pieces of related information into a collapsible panel. This is what got me working on this user-control.
This control is very easy to use. The control exposes some public properties to set the data, look 'n' feel and events for the panel. By setting these properties, the collapsible panel can be used to group information very nicely. Also, we could extend it to add any control to the panel.
Using the code
The user control is divided into 3 regions - header, body and footer.
- The header region contains the clickable image (for expand/collapse functionality) and the title for the panel.
- The body contains the controls that would encapsulate the information to be displayed in the panel.
- The footer has the buttons for navigation.
The user control exposes methods to add titles, controls and buttons to the panel. It also exposes properties to set the look 'n' feel of the panel. To use the panel in your web page, you need to instantiate it and set the required properties as shown below.
ucMyColPanel1.TableWidth = Unit.Pixel(500);
ucMyColPanel1.AddTitle();
ucMyColPanel1.HeaderClass = "alertHeader";
ucMyColPanel1.HeaderTitleText = "Descriptions";
ucMyColPanel1.AddDataGrid();
ucMyColPanel1.DGItemClass = "dgItem";
ucMyColPanel1.DGHeaderClass = "dgHeader";
ucMyColPanel1.DGAlternatingItemClass = "dgAlternatingItem";
ucMyColPanel1.DGGridLines = GridLines.None;
ucMyColPanel1.DGWidth = Unit.Percentage(70);
ucMyColPanel1.DGCellPadding = 2;
ucMyColPanel1.DGCellSpacing = 1;
ucMyColPanel1.DGDataSource = m_oDescriptionDS;
ucMyColPanel1.DataBindGrid();
ucMyColPanel1.AddButton();
ucMyColPanel1.myButton.FooterButtonText = "Add Description";
ucMyColPanel1.myButton.FooterButtonClass = "flatFormElement";
ucMyColPanel1.myButton.ClickEvent += new System.EventHandler(this.btn1_click);
ucMyColPanel1.AddFooterSpacer();
ucMyColPanel1.AddButton();
ucMyColPanel1.myButton.FooterButtonText = "Cancel";
ucMyColPanel1.myButton.FooterButtonClass = "flatFormElement";
ucMyColPanel1.myButton.ClickEvent += new System.EventHandler(this.btn2_click);
To get the project working you will need to place the images and includes folders in your wwwroot directory or in your home directory (if it is different from wwwroot). Also place the usercontrols folder inside the project "MyCollapsiblePanel" folder. Set "TestMyColPanel.aspx" as the start-up page. Now you are ready to run and debug the code!
Points of Interest
The best part of this exercise was that I learnt how to effectively expose a control's event without exposing the control itself!
I was faced with the problem of attaching event handlers to different buttons that could be added to the collapsible panel. I started off with declaring an event in my usercontrol which would be fired when a (any) button is clicked. The event was a public event to which the user could attach event handlers from outside. For testing, I did a page redirection in the event handlers. But all button clicks seemed to take me to the same page, irrespective of which button was clicked. What was happening was that the event handler was not getting chained to the specific instance of the button!!!
To solve the issue, I created an inner class in my user control called MyButton
which would encapsulate a Button and an event. I made the event public so that I could set its handlers from outside. When I needed to add a button to my user control, I would instantiate the MyButton
class and add the button (member of MyButton
class) to the user control. The click event of the button would then cause the firing of this event (which is specific to this button). This way, I was able to expose my control's event without exposing the control.
I am showing the MyButton
class here:
public class MyButton
{
protected Button btnAction;
public event EventHandler ClickEvent;
public MyButton()
{
btnAction = new Button();
btnAction.Click += new System.EventHandler(this.ClickHandler);
}
public void AddMyButton(TableCell tcBody)
{
tcBody.Controls.Add(btnAction);
}
public string FooterButtonText
{
set
{
btnAction.Text = value;
}
}
public string FooterButtonClass
{
set
{
btnAction.CssClass = value;
}
}
private void ClickHandler(object sender, EventArgs e)
{
if(ClickEvent != null)
ClickEvent(sender, e);
}
}
Well, that's my little collapsible panel for the time being till I come up with some enhancements!