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.
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
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
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.
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.
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
DataValueField, similar to that of a standard dropdownlist control, for text content of the list items and the value of each list item, respectively.
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.
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.
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.
style="Z-INDEX: 101; LEFT: 20px; POSITION: absolute; TOP: 20px">
<ddms:multiselectdropdown id="MultiSelectDropDown1" runat="server">
style="Z-INDEX: 100; LEFT: 20px; POSITION: absolute; TOP: 60px">
<ddms:multiselectdropdown id="Multiselectdropdown2" runat="server">
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,
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
protected void Page_Load(object sender, System.EventArgs e)
this.MultiSelectDropDown1.DataSource = GetCurrencyDataSource();
this.MultiSelectDropDown1.DataTextField = "Description";
this.MultiSelectDropDown1.DataValueField = "CurrencyID";
this.MultiSelectDropDown1.AutoPostBack = true;
this.Multiselectdropdown2.DataSource = GetEmployeeDataSource();
this.Multiselectdropdown2.DataTextField = "EmpName";
this.Multiselectdropdown2.DataValueField = "EmpID";
this.Multiselectdropdown2.AutoPostBack = false;
this.MultiSelectDropDown1.CallingPage = this;
this.Multiselectdropdown2.CallingPage = this;
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,
this.tbSelectedFullText.Text = string.Empty;
this.tbSelectedOptionsValue.Text = string.Empty;
this.tbSelectedOptionsValue.Text = args.SelectedOptionValueText;
this.tbSelectedFullText.Text = args.SelectedOptionText;
foreach(string selectedOption in args.SelectedOptionList)
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.
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.,
- 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.
- 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.