Introduction
It’s an Internet era where everything is coming to the Internet. Nowadays, users seem to be more diverted towards online purchasing than ever before. Day by day, it’s getting harder for companies to make their online users happy because of tough competition. One thing which is common across all websites on the Internet in terms of getting more and more hits and making their Internet shop successful is their use of state of the art web tools and controls, and the way they are presented on the web page along with other information.
Visual Studio .NET comes with a wide range of web server controls. These controls possess DHTML characteristics (e.g. Autopostback
and EnableSessionState
), and at the same time are easy to use. They also require less space to present a bunch of information on the web page. Two of these controls are DropdownList
and CheckboxList
. Both of the controls are powerful and rich in functionality in the sense that they provide efficient ways to add and delete individual items, exhibit multi-select functionality, and also have a DataSource
property which makes them qualify as data bound controls. One limitation which is common in both the controls is the way they display information on the page. In comparison to other controls, they take relatively more space to render information. But, now we have got to a stage where companies are tying up with other companies and trying to get involved in more than one businesses. They like to see as much content on their site as possible. They can't afford controls which take a huge amount of space just to display one type of information.
When I got into the same situation where I had to create a search page having 15 to 20 search filters and each with more than 25 items, I decided not to occupy the whole page with list boxes or checkbox lists, but to develop a user control that would not only display a full list of checkbox items but will also act as a dropdown.
About the User Control
It’s an easy to use and lightweight control. The code is also fairly simple to understand. I have developed it using .NET and C# on the server side and JavaScript for client side scripting. Although it’s not a full blown web server control, it does provide with some useful features that help users in displaying and managing information on the page easily. Following is a small list of those features:
Autopostback
A property by which the page will be posted back to the server automatically on firing the OnSelectedItem
event, which will happen only when the value of this property is set to true
and the toggle on/off button is pressed.
EnableViewState
A property that says whether the current value of the control must be saved in the __VIEWSTATE
hidden field and restored during a page postback. For this control, to display the list of selected options, I have used the ASP.NET TextBox
control that will take care of the view state for our control.
DataSource
Through this property, the control gets or sets the data source which is of type DataTable
. It makes the control a true data bound control. Other than this property, the control also supports DataTextField
and DataValueField
, similar to that of a standard dropdownlist control, for text content of the list items and the value of each list item, respectively.
- Z-Index
This property sets the stack order of our user control. It is very useful when more than one instance of the control are going to be used on the same page. Since the control expands in the downward direction, an instance with greater stack order is always in front of an instance with lower stack order.
Expand/Collapse
Just like a normal dropdown list control, this user control can be collapsed automatically by clicking anywhere on the page or on the control itself, except on the region which displays the selection list. This is because of the fact that the user might want to select more than one item.
Selected Options
On postback, a control will pass its current state to the server in the form of a comma separated list which can be used for further processing.
Using the Code
Using this control in your ASP.NET project is fairly simple as it gets or sets everything through properties it exposes. On the page, it first needs to be registered, which can be done by pasting the following line on top of your ASPX page:
<%@ Register TagPrefix="DDMS"
TagName="MultiSelectDropDown" Src="MultiSelectDropDown.ascx" %>
After the registration is done, the control can be initialized by pasting the following code anywhere on the page but within the HTML body. It’s important to note that in the attached demo project, I have encapsulated the control inside <DIV>
tags which is not required, of course but, as I mentioned above, to avoid z-index problems, it’s better to enclose it with <DIV>
and give it an z-index value based on the order of appearance on the page.
<div id="divMultiSelectDropDown1"
style="Z-INDEX: 101; LEFT: 20px; POSITION: absolute; TOP: 20px">
<ddms:multiselectdropdown id="MultiSelectDropDown1" runat="server">
</ddms:multiselectdropdown><br>
<br>
</div>
<div id="divMultiSelectDropDown2"
style="Z-INDEX: 100; LEFT: 20px; POSITION: absolute; TOP: 60px">
<ddms:multiselectdropdown id="Multiselectdropdown2" runat="server">
</ddms:multiselectdropdown>
</div>
That’s all from the ASPX side. It’s time to write a bit of server-side code. To load and configure the control, the following lines of code can be pasted in the Page_OnLoad
event. Two separate instances of the control, MultiSelectDropDown1
and MultiSelectDropDown2
, are being used in the code below. CallingPage
is a property exposed by the control that will supply a reference of the host page to the control. By using this reference, the user control will emit the necessary code for the __doPostBack
method.
protected void Page_Load(object sender, System.EventArgs e)
{
if(!this.IsPostBack)
{
this.MultiSelectDropDown1.DataSource = GetCurrencyDataSource();
this.MultiSelectDropDown1.DataTextField = "Description";
this.MultiSelectDropDown1.DataValueField = "CurrencyID";
this.MultiSelectDropDown1.AutoPostBack = true;
this.MultiSelectDropDown1.DataBind();
this.Multiselectdropdown2.DataSource = GetEmployeeDataSource();
this.Multiselectdropdown2.DataTextField = "EmpName";
this.Multiselectdropdown2.DataValueField = "EmpID";
this.Multiselectdropdown2.AutoPostBack = false;
this.Multiselectdropdown2.DataBind();
}
this.MultiSelectDropDown1.CallingPage = this;
this.Multiselectdropdown2.CallingPage = this;
this.MultiSelectDropDown1.OnItemsSelected +=
new MultiSelectDropDownDelegate(MultiSelectDropDown1_OnItemsSelected);
}
One last thing is to register the OnSelectedItem
event and to provide its event handler. For event arguments, I have created a separate class with the name MultiSelectDropDownItemSelectedEventArgs
. That will wrap the arguments (__EVENTARGUEMNT
) and pass them to the event handler. The demo project will give you the output shown below:
private void MultiSelectDropDown1_OnItemsSelected(object sender,
MultiSelectDropDownItemSelectedEventArgs args)
{
this.tbSelectedFullText.Text = string.Empty;
this.tbSelectedOptionsValue.Text = string.Empty;
this.lbSelectedItemList.Items.Clear();
this.tbSelectedOptionsValue.Text = args.SelectedOptionValueText;
this.tbSelectedFullText.Text = args.SelectedOptionText;
foreach(string selectedOption in args.SelectedOptionList)
this.lbSelectedItemList.Items.Add(selectedOption);
}
Scope
Before I actually started working on the control, like most other developers, I tried to find a control with the similar look and functionality on the internet to support code re-usability (you know what I mean ;). After failing to do so, I decided to take on this endeavor myself and for those who might be interested in using it in their projects.
As far as the scope of the control is concerned, it can be extended to both versions of .NET (1.1 and 2.0). Note that, not only web pages but also other user controls can host this user control.
Points of Interest
I would like to comment on a few things that I learned, and a few small problems I faced while writing this control.
CheckBoxList and <ASP:CheckBox> were not the right choice:
It took some of my time to decide which control I will use to display the list of checkboxes, because CheckBoxList
doesn't provide any facility to set the attributes for its individual items. Even the server side <ASP:Checkbox>
was not a feasible option as it doesn't have a Value
property unlike an HTML checkbox.
UserControl's CLIENTID
It’s important to remember that while developing a user control that will act as a container for other child controls and will have multiple instances on a page, always access child controls by concatenating their IDs with that of the parent control.
- __doPostBack , EVENTARGUMENT and EVENTTARGET
I had to write my own version of __doPostBack
because the default version of __doPostBack
is available if and only if there is at least one .NET built-in server control on a page. Since our user control was going to act as a server side control in itself, I couldn't rely on the __doPostBack
generated by other .NET server controls as they might or might not be present on the page at all.
Below are some of the features I would like to see in the control. I would be glad If anyone out there upgrades the control by implementing the following features; otherwise, I will do it myself whenever time permits me (which means never!!)
Add
method for the Items collection, i.e., Items.Add()
.- Changing the orange color for
OnMouseOver
to the Windows default 'blue' color. - Ability to change the size of the control through a property.
- Postback through AJAX.
Update 1.1
- Firefox support has been added.
- VB.NET version added in the attached demo project (only the main file with the name "MultiSelectDropDown.ascx.vb").
- All style related code is now separated from HTML. A new CSS file has been added to increase performance and speed.