Introduction

When a developer wants to display a list of items with the ability to select some of them, there are not many options available, actually it comes to only two:

  1. List box
  2. Check box list

Both have some disadvantages.

The list box control selection is just highlighting of a row, which is visually weak type of selection, multiple selection is not intuitive and is not convenient for the end user.

Check box list has a strong visual selection type but takes a lot of space if the list is long enough.

It would be nice to use something like a drop-down list, but unfortunately the drop-down list control does not support multiple-item selection.

The combination of the drop-down list and check box list would be ideal for this purpose.

So when the time had come and the web portal that I developed required to have such selection list, I started to do my home work and look for a suitable solution on the Internet.

I found a few, but was not satisfied with the complexity and overall amount of code to implement them.

I also found a nice JQuery extension, but it was pure client side solution and I had something else in mind.

I decided to develop my own server side control.

I realized that it would be JavaScript driven, because I want to implement the client side click event to open and close the drop-down list.

My JavaScript of choice would be JQuery, which is very popular nowadays.

I also realized that CSS will be involved to style this control the way I wanted.

So the entire solution will be:

  1. server side control
  2. reference to JQuery library
  3. CSS(either a file of just a style tag)
  4. One image(an arrow down)

Server side control

Obviously this control will inherit from CheckBoxList control.

I added three  public properties (Title, ImageURL, and OpenOnStart) and overrode the Render procedure.

For my convenience when rendering the control, I added the reference to JQuery library inside the Render procedure, but you can do it differently.

So this is the source:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CodeProjectWeb
{
    public class CheckBoxListDropDown : CheckBoxList
    {
        //First row
        public string Title { get; set; }

        public string ImageURL { get; set; }

        //Expand or hide on start
        public bool OpenOnStart { get; set; }

        /// Display as a dropdown list
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            //default css class
            if (string.IsNullOrEmpty(this.CssClass))
                this.CssClass = "ddlchklst";

            //first row division: 
            string divFirstRow = @"
            <div>
               {0} <img id=""{1}"" style=""float: right;"" src=""{2}"" />
            </div>";

            //unorder list:
            string ulTag = "<ul style=\"display:{1}\" id=\"{0}\" >";

            //check box:
            string chkbox = "<input id=\"{0}\" name=\"{1}\" type=\"checkbox\" value=\"{2}\"{3} />";

            //title for check box:
            string label = "<label for=\"{0}\">{1}</label>";

            string jqueryToggleFunction = @" 
            <script type=""text/javascript"">
                $(document).ready(function () {{
                    $(""#{0}"").click(function () {{
                        $(""#{1}"").toggle(""fast"");

                    }}); 
                        $("".{2} li:even"").css(""background-color"", ""#efefef"")
                }}); 
            </script>";

            //rendering the control:

            // optionally you can place reference to jquery library here:
            writer.WriteLine("<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js'></script>");
            writer.WriteLine(string.Format("<div class=\"{0}\">", this.CssClass));
            writer.Write(string.Format(divFirstRow, this.Title + "  ", base.ClientID + "_arrowDown", ImageURL));
            writer.WriteLine();
            writer.Indent++;
            writer.WriteLine(string.Format(ulTag, base.ClientID + "_ul", OpenOnStart ? "block" : "none"));

            for (int index = 0; index < Items.Count; index++)
            {
                writer.Indent++;
                writer.WriteLine("<li>");
                writer.Indent++;

                writer.WriteLine(string.Format(chkbox,
                    base.ClientID + "_" + index.ToString(),
                    base.ClientID + "$" + index.ToString(),
                    Items[index].Value,
                    (Items[index].Selected ? " checked" : " ")));

                writer.WriteLine(string.Format(label, base.ClientID + "_" + index.ToString(), Items[index].Text + " "));
                writer.Indent--;

                writer.WriteLine("</li>");
                writer.WriteLine();
                writer.Indent--;
            }
            writer.WriteLine("</ul>");
            writer.WriteLine("</div>");
            writer.Write(string.Format(jqueryToggleFunction, base.ClientID + "_arrowDown", base.ClientID + "_ul", this.CssClass));
        }

    }
}

Testing the control

ASPX page:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DropdownCheckcs.aspx.cs"
    Inherits="CodeProjectWeb.DropdownCheckcs" %>

<%@ Register Assembly="CodeProjectWeb" Namespace="CodeProjectWeb" TagPrefix="cc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
        .ddlchklst
        {
            width: 170px;
            border:solid 1px silver;
        }
        .ddlchklst ul
        {
          margin:0;
          padding:0;
           border-top:solid 1px silver;
            }
        .ddlchklst li
        {
            list-style: none;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <cc1:CheckBoxListDropDown ID="ddlchklst"  runat="server" Title="Select what you need" OpenOnStart="true" ImageURL="/images/DropDown.PNG">
        </cc1:CheckBoxListDropDown>
    </div>
    <div>
        <asp:Button ID="btn" runat="server" Text="Save" OnClick="btn_Click" />
    </div>
    </form>
</body>
</html>

Please not that you have to register the control:

<%@ Register Assembly="CodeProjectWeb" Namespace="CodeProjectWeb" TagPrefix="cc1" %>

User your own Assembly and Namespace to register.

Use the following image to display the down arrow:  DropDown.PNG
Place this image into convenient location and set the ImageURL property correctly.

Also this is our CSS: 

<style type="text/css">
        .ddlchklst
        {
            width: 170px;
            border:solid 1px silver;
        }
        .ddlchklst ul
        {
          margin:0;
          padding:0;
           border-top:solid 1px silver;
            }
        .ddlchklst li
        {
            list-style: none;
        }
    </style>

ASPX.cs

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CodeProjectWeb
{
    public partial class DropdownCheckcs : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                string[] ds = new string[] { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
                this.ddlchklst.DataSource = ds;
                this.ddlchklst.DataBind();
            }
        }

        protected void btn_Click(object sender, EventArgs e)
        {

            foreach (ListItem li in this.ddlchklst.Items)
           {
               Response.Write( li.Value +": " +li.Selected.ToString() + "
");
           }

        }
    }
}

Result

This is the result you will see when you expand the list:
DDL.png

Conclusion 

As you can see, this control is easy to implement and you can change the way it looks by changing the Render procedure and/or CSS class.

If you like this article, please, vote for it. It is important, because it allows more programmers to utilize this code.