Developing Multicolumn-DropDown/DropDownList with ASP.NET, the GridView and the AJAX Control Toolkit

During the last months I was developing an ASP.NET application and I needed a dropdownlist to display multiple columns in each item. Everyone with a little knowledge in Web-development knows, that HTML doesn’t contain built-in support for multicolumn-DropDowns. HTML only knows a <select>-Tag that can contain multiple <option>-Tags, but each <option>-Tag just represents one column in the dropdown.

In this post we’ll take a look at different possiblities to display the properties of a simple Friend-class in one dropdown-“option”. The Friend-Class looks like this:

public class Friend
{
  public Guid ID { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public DateTime BirthDay { get; set; }
}

Below you see the four approaches we’ll look at in this post:

  • The easieast way to do it: Using string concatenation
  • Use third-party controls that have the multicolumn-feature
  • Develop your one multicolumn-DropDown with AJAX Control Extenders
  • Make the multicolumn-DropDown usable for many rows

The easiest way to do it: Using string concatenation

The easiest way I can think of is to use simple string concatenation and a monospace font like courier new. First thing to do is to add an asp:DropDownList to your page. Don’t forget to set it to a monospace font. You can do this via style-Attribute.

<asp:DropDownList ID="friendDropDownList" runat="server"
style="font-family: 'Courier New', Courier, monospace" />

The DropDownList can be filled up in code-behind, e.g. in the Page_Load-Event. The most tricky part is to add multiple blanks. The DropDownList automatically encodes the added string to HTML and all blanks per default become one blank. That would cause the columns not to be displayed exactly below each other. One solution to this is to add blanks as a unicode escape sequence (\u00A0). The DropDownList will automatically convert these into “&#160″which can be interpreted by the browser.

protected void Page_Load(object sender, EventArgs e)
{
  PseudoFriendDataAccess da = new PseudoFriendDataAccess();
  List friendList = da.LoadAllFriends();

  foreach (Friend f in friendList)
  {
    string text = string.Format("{0}|{1}|{2}",
      f.FirstName.PadRight(10,'\u00A0'),
      f.LastName.PadRight(10,'\u00A0'),
      f.BirthDay.HasValue?
      f.BirthDay.Value.ToString("dd.MM.yyyy"):
      "".PadRight(10,'\u00A0'));
    friendDropDownList.Items.Add(
      new ListItem(text,f.ID.ToString()));
  }
}

The result for the DropDownList above feels like this:

I’ve to add that this solution via string concatenation doesn’t look really cool. So let’s take a look at other approaches.

Use third-party controls that have the multicolumn-feature

There are different third-party controls that have the multicolumn-feature. E.g. Infragistics has a WebCombo-Control that can display multiple-Columns. On Codeproject there’s also a Control availabe, but unfortunately with no source-code of the control itself: http://www.codeproject.com/KB/custom-controls/multiColsDD_List.aspx. I looked at this control, but I think it isn’t a great idea to use it for a professional application without having support and without having full source code.

So I’ve tried the Infragistics WebCombo. It worked very well up to 20 records when displaying about 5 columns. With 200 records it became very very slow in IE7. E.g. while the mouse cursor moved from item 90 to item 100, the WebCombo still showed the mouseOver-Color on item 90, then the mouseOver-Color moved slowly to item 91, 92, 93… The time used for this task was over 1 second till the mouseOver-color reached item 100. As I needed a multiple column dropdownlist with at least 200 items, the Infragistics WebCombo was no solution for me (I’ve used NetAdvantage_ASPNET_2008 Vol. 2_CLR2.x). Maybe the team of Infragistics can check this and make it faster for IE7.

So after evaluation more dropdowns from other vendors and after a phone call with Jean-Claude Trachsel, another ASP.NET-Professional@Trivadis, I decided to create a multiplecolumn-dropdownlist on my own using the AJAX Control Extenders and the build-in GridView.

Develop your one multicolumn-DropDown with AJAX Control Extenders and ASP’s GridView

Starting the development of a multicolumn-dropdown, the first thing to is is to add an UpdatePanel to your site:

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
  <ContentTemplate>
    <!-- all other content goes here -->
  </ContentTemplate>
</asp:UpdatePanel>

Inside the <ContentTemplate>-Tag of the UpdatePanel I place a TextBox and an ASP-Panel. The Panel’s Style is set, so that it isn’t visible per default. Below the Panel I’ve placed a DropDownExtender from the AJAX Control ToolKit. Download the Toolkit here. The DropDownExtender has a DropDownControlID- and a TargetControlID-Property. When the TargetControl is clicked (here the txtFriend-TextBox) the DropDownControl (here the FriendDropDown-Panel) becomes visible.

<asp:TextBox ID="txtFriend" runat="server"
  Width="100px" ReadOnly="true" />
<asp:Panel runat="server" ID="FriendDropDown"
  Style="display: none; visibility: hidden;">
  <!-- GridView  goes here -->
</asp:Panel>
<cc1:DropDownExtender ID="DropDownExtender1" runat="server"
  DropDownControlID="FriendDropDown"
  TargetControlID="txtFriend">

As I’ve added the DropDownExtender out of Visual Studio’s ToolBox, the following Register-Directive was created automatically on my page and also an assembly-reference was set automatically.

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

Next you’ve to add a GridView inside the FriendDropDown-Panel. Just drag it out of the toolbox and set the properties you need. Here the GridView is named FriendGridView. Two Eventhandlers are defined for the events RowDataBound and SelectedIndexChanged, which are necessary for this multicolumn-scenario. But before we look at the Eventhandlers in the Codebehind-file, first look at the invisibleColumn stye, which is set on the first BoundField in the GridView.


<asp:GridView ID="FriendGridView" runat="server" 
  AutoGenerateColumns="false"
  OnRowDataBound="FriendGridView_RowDataBound"
OnSelectedIndexChanged="FriendGridView_SelectedIndexChanged">
  <RowStyle BackColor="#DDDDDD" />
  <Columns>
    <asp:BoundField DataField="ID"
      HeaderStyle-CssClass="invisibleColumn"
      ItemStyle-CssClass="invisibleColumn" />
    <asp:BoundField DataField="FirstName"
                    HeaderText="Firstname" />
    <asp:BoundField DataField="LastName"
                    HeaderText="Lastname" />
    <asp:BoundField DataField="Birthday"
                    HeaderText="Birthday"
                    DataFormatString="{0:dd.MM.yyyy}" />
  </Columns>
  <HeaderStyle BackColor="Blue" ForeColor="White" />
  <AlternatingRowStyle BackColor="#EEEEEE" />
  <SelectedRowStyle BackColor="#999999" />
</asp:GridView>

The FriendGridView has four columns, each bound to a property of the Friend-class. As the ID-property shouldn’t be visible to the user, the Headers and Items of this BoundField are using the CSS-class “invisibleColumn”. This class simple set’s the width to zero and the display-property to none, so that this column is not visible to the user, but you can access it on a postback, e.g. to update the Friend-object in a database, where you’ll need the ID. On the page I’ve also set the font-family and font-size, as you can see below.


<style>
  .invisibleColumn
  {
    display: none;
    width: 0px;
  }
  body
  {
      font-family:Arial;
      font-size:12px;
  }
</style>

The next thing to do is to add the EventHandlers in the Codebehind-file. In the SelectedIndexChanged-Event the Text of the txtFriend-TextBox is set to the value of the second cell of the selectedRow. The second cell contains the FirstName. As the GridView is in an UpdatePanel with the TextBox, only this part of the Page is refreshed on the Clientside (via AJAX).

protected void FriendGridView_SelectedIndexChanged(...)
{
  // assign firstname
  if (FriendGridView.SelectedRow != null)
    txtFriend.Text = Server.HtmlDecode(
      FriendGridView.SelectedRow.Cells[1].Text);
  else
    txtFriend.Text = "";
}

To display some mouseover-effects on the GridView and to allow selection by clicking on a row, the RowDataBound-Eventhandler is necessary. There some Javascript is added to each row of the GridView.

protected void FriendGridView_RowDataBound(...)
{
  if (e.Row.RowType != DataControlRowType.DataRow)
    return;

 e.Row.Attributes["onmouseover"]="this.style.cursor='hand';"
 +"this.originalBackgroundColor=this.style.backgroundColor;"
 +"this.style.backgroundColor='#bbbbbb';";

 e.Row.Attributes["onmouseout"] =
 "this.style.backgroundColor=this.originalBackgroundColor;";

 e.Row.Attributes["onclick"] =
 ClientScript.GetPostBackClientHyperlink(this.FriendGridView,
  "Select$" + e.Row.RowIndex);
}

The most important on the snippet above is the last line that adds the onclick-Attribute to the row. With this attribute and the value of it the row is selected via click and doesn’t need a Select-Button, like the default-GridView needs to select a row. When a row is clicked, the SelectedIndexChanged-Event is automatically triggered by that JavaScript and the txtFriend-TextBox is set to the selected firstname in the Eventhandler for SelectedIndexChanged.

To make it really working, the last thing to do is to add the EnableEventValidation-Attribut to your page and set it to false. This allows the JavaScript from the snippet above to invoke the SelectedIndexChanged-Event. As an alternative to setting this attribute to false you can take a look at the RegisterForEventValidation-Method of ClientScriptManager that you can call in the Render-Method of your page.

<%@ Page Language="C#" EnableEventValidation="false" ...

That’s all. Now let’s take a look at the dropdown. Just fill it in the Page_Load-Event with the same data as the string-concatenated dropdown before.

protected void Page_Load(object sender, EventArgs e)
{
  PseudoFriendDataAccess da = new PseudoFriendDataAccess();
  List friendList = da.LoadAllFriends();

  FriendGridView.DataSource = friendList;
  FriendGridView.DataBind();
}

Below you see the created multicolumn-Dropdown. I’ve selected Christoph and reopened the DropDown again. The TextBox displays his firstname and the GridView shows the selected row.

ajaxExtenderWithGridViewDropDown

Make the multicolumn-DropDown usable for many rows

If you’ve more rows, the dropDownList should be scrollable. To add scrollsupport, simply extend the Style-Property of the FriendDropDown-Panel and add an overflow– and a max-height-attribut. Set the overflow-attribut to scroll, and the max-height to a value of your choice.

<asp:Panel runat="server" ID="FriendDropDown"
  Style="max-height:150px;overflow:scroll;
         display:none; visibility: hidden;">

For test-purposes I’ve just filled the FriendDropDown-GridView with more than 4 Rows to get the scroll behavior. In Firefox it looks great.

scrollableFireFoxDropDown

Unfortunately Internet Explorer 7 doesn’t calculate the size of the vertical scrollbar to the Panel (it’s a div-tag in HTML) containing the GridView. So in Internet Explorer 7 you won’t see the total of the last column. Instead of that you have to scroll horizontally.

scrollableIE7DropDown

To get very simply rid of that, I’ve added a dummy-column as the last column (and so the column on the right side) to the GridView that has a width of 15px. 15px is about the width of the vertical scrollbar.

<Columns>
  ...
  <asp:TemplateField ItemStyle-Width="15px" />
</Columns>

Now that dummy-column will be behind the vertical scrollbar and the user is able to see all necessary columns.

scrollableIE7BetterDropDown

If the user scroll’s to the right with the horizontal scrollbar, he just sees the dummy-column.

scrollableIE7BetterDropDown2

So that’s all.

I think you can develop a control out of that stuff if necessary.

If you have additional information about developing multicolumn-Drowdowns or any feedback, just write a comment or a mail via the contact-formular on my homepage. Grab the source here: 20090919_ThomasClaudiusHuber_MultiColumnDropDown.zip. Please write a comment if you like it on this blogpost.

If you found this article useful, just feel free to kick it for me:

kick it on DotNetKicks.com

Thanks a lot. :-)

Share this post

Comments (48)

  • seasoft Reply

    Can you send the source code to me? as soon as possible.
    Tks!

    October 28, 2008 at 7:53 am
  • jo_benji Reply

    hello
    I tried to put an update panel in a panel using a listbox instead of the gridview.
    I don’t know if this makes sens.My problem is that the dropdown menu is not working .Here ‘s my code

    Thank you if you can help

    November 5, 2008 at 6:10 pm
  • Raj Reply

    This is cool and what I was looking for. Can you send me the source code. (why not host it someplace where others can find and use it too – maybe codeplex)

    December 15, 2008 at 6:41 pm
  • vaibhav Srivastava Reply

    My dropdown list on expanding covering the complete page, I have tried the option of size but even that doesn’t seem to work, I am using IE7 that is what creating the problem. Below is the code:

    Let me know if you have any suggestions to resolve the issue.

    January 4, 2009 at 4:07 am
  • byteater Reply

    cool and great and simply clear what is to do! no need to send me the source :-))

    thx thomas and google

    January 14, 2009 at 8:38 pm
  • Teena Reply

    hi,
    The code works fine but i am using Listview instead of grid , this is also working fine. I want the panel to be shown till the multiple checkboxes are selected on listview. But as soon as a checkbox is selected the Listview panel closes, I want to avoid this. How do i achieve this?

    January 15, 2009 at 7:24 pm
  • hubethom Reply

    Hi together,

    I’ll post the source this weekend in a new blogpost. Have a look at the blog on monday.
    @Ray: That would be a great idea, maybe I’ll do that next week.
    @Teena: I’ll take a look at that, and also post about that. I haven’t tried it with the ListView-Control. But what do you want to display in the textBox when multiple elements are selected?

    Cheers
    Thomas

    January 16, 2009 at 8:41 am
  • Rahul Reply

    Hi,

    Really nice article… Instead of simply giving a downloadable code, you explained
    very well how we can achieve the task….

    Great work. Thanks for the article.

    Rahul……

    January 20, 2009 at 6:34 am
  • hubethom Reply

    Hi @all,

    find the code for this post here.

    Cheers
    Thomas

    January 23, 2009 at 4:23 pm
  • .NET Rocker » Blog Archive » How-to deploy the Crystal Reports Basic Runtime that’s included in Visual Studio 2008 Reply

    […] This week I’ve to deploy an ASP.NET application containing about 20 reports that have been created with the Crystal Reports Basic Runtime which is included in Visual Studio 2008. (By the way, the application also contains a lot of AJAX-Functionality. It uses the "AJAX Control Toolkit-based" MultiColumnDropDown that I’ve described in a previous post). […]

    February 2, 2009 at 4:31 pm
  • ken Reply

    is it posibly to use a database connection in your code (gridview) ?

    February 16, 2009 at 11:21 pm
  • hubethom Reply

    Hi Ken, of course it is possible to use a database connection to fill up the gridView.

    February 22, 2009 at 12:11 pm
  • Ken Reply

    hi

    What I mean is your first example, can this example be used in a database example ?

    February 26, 2009 at 11:39 pm
  • umair Reply

    Hi bro..
    The last technique is really good.
    Thanks a lot.
    But i m facing one small issue which is whenever my cursor is on txtFriend a gridview populates but it starts some space before the txtFriend. How i can populate the gridview in a specific position?

    Reply..

    July 14, 2009 at 7:42 pm
  • Nanak Reply

    Your logic is great, and works very good…. as real exmaple, but i want to make custom control with same logic, can you help me with that…. because in now when ever i have to use it i have to write many things…. how can i make my custom control… please help me, as i am now exahusted….. with experimenting with multicolumn dropdown , i also created one…. like hiding panel… but didnt looked like real one…. my mail nanak.software@yahoo.com

    August 31, 2009 at 10:06 am
  • nutty Reply

    hi thom, I was able to run your code just fine. However I want to use it inside itemtemplate in gridviewMain. how can I pass the SelectedIndexChange in gridview2(pop) to that of gridviewMain.? heres my code.

    <asp:TextBox ID=”txtFriend” runat=”server” Text=”>

    <asp:Label ID=”Label1″ runat=”server” Text=”>

    <%–cc1:DropDownExtender ID=”DropDownExtender1″ runat=”server”

    DropDownControlID=”FriendDropDown”

    TargetControlID=”” /–%>

    March 2, 2010 at 11:47 am
  • nutty Reply

    <asp:TextBox ID=”txtFriend” runat=”server” Text=”>

    <asp:Label ID=”Label1″ runat=”server” Text=”>

    <%–cc1:DropDownExtender ID=”DropDownExtender1″ runat=”server”

    DropDownControlID=”FriendDropDown”

    TargetControlID=”” /–%>

    March 2, 2010 at 11:48 am
  • nutty Reply

    hope to hear from you soonest.

    March 2, 2010 at 11:52 am
  • nutty Reply

    Heres my code in the SelectedIndexChanged

    protected void FriendGridView_SelectedIndexChanged(object sender, EventArgs e)

    {

    TextBox txtFrnd = (TextBox)gvHourlyStacks.FindControl(“txtFriend”) ;

    // assign firstname

    if (FriendGridView.SelectedRow != null)

    txtFrnd.Text = Server.HtmlDecode(

    FriendGridView.SelectedRow.Cells[0].Text);

    else

    txtFrnd.Text = “”;

    }

    March 2, 2010 at 11:55 am
  • nutty Reply

    Hi bro,
    I was able to run your code just fine. But I want to embed it in another gridview(main) in an item template. I had a hard time filling the textbox during select index change in the gridview dropdown. Appreciate if you can help me. Please let me know if I need to post the code.

    March 3, 2010 at 12:08 am
  • hubethom Reply

    Hi nutty,

    my time is limited and currently I can’t give any support to this. Sorry.

    Thomas

    March 15, 2010 at 11:18 pm
  • nutty Reply

    Hi Thom,

    Thanks for the info.

    Regards,
    Nutty

    March 16, 2010 at 5:37 am
  • Kolpa Reply

    Hi dude

    I want to use different thing which refresh page instead of “ClientScript.GetPostBackClientHyperlink”. Is it possible?

    April 22, 2010 at 9:21 pm
  • Kolpa Reply

    hi dude

    I am sorry. I want to use different thing which does not refresh page instead of “ClientScript.GetPostBackClientHyperlink”. Is it possible?

    April 22, 2010 at 9:25 pm
  • Farai Reply

    Hi Thom. I’m Farai, based in South Africa. A big thanks to you for this great example. You wont imagine how much trouble I had to go through, to finally get a working solution like this one. You are the man. Keep it up!!

    May 1, 2010 at 3:07 pm
  • Jen Reply

    Simple, elegant and works like a champ! Thanks for sharing :)

    June 24, 2010 at 3:40 pm
  • Dmitriy Reply

    Hi Thomas,
    I like your step-by-step explanation how to build the multi-column ASP control. I believe it should be compiled into DLL in order to use one in any ASP.NET application. I will be greatly appreciated if you send me the source of your example.
    Thanks in advance,
    Dmitriy

    June 30, 2010 at 7:33 pm
  • Roy Reply

    how I can create load on demand feature in combo box using your second option ?

    January 31, 2011 at 8:54 am
  • Abhishek Reply

    Hi,

    If you could share your source code it would be really helpful.

    Your approach is exactly what i needed.

    Hope you would help me out.

    Thanks a lot,
    Abhi

    January 31, 2011 at 11:46 am
  • Sruti Reply

    hi please send me the simple code its best quote and help for all

    August 26, 2011 at 6:45 am
    • hubethom Reply

      Hi Sruti,

      i´ve just posted a link to the Source-Code at the end of the blog-post. :-)

      September 13, 2011 at 2:25 pm
  • empee1 Reply

    Nice!
    You can even set Visible=”false” for the ID column in stead of using style, and overflow:auto for the panel to get scroll bars only when needed.

    February 3, 2012 at 10:57 pm
  • Gurdeep Reply

    Thanks Thomas for great tool,

    I have however extended this cool to use different datasources, styling etc. and will be comiling it in order to use it out of box as one of the reader requested above. I will put up the source code soon and update here.

    Bye for now.

    February 10, 2012 at 3:35 pm
  • NaingNaing Reply

    Thanks for your coding. I already tried with your coding but I can’t run.Your zip file is Ok .When I copied your coding and ran in my PC,can’t run.So Please tell me any refrence for multiple columns in asp.net drop down list.
    Thank and Best Regards,

    September 23, 2012 at 5:32 am
    • Thomas Claudius Huber Reply

      Hi Naing, it’s not possible for me to give you support for the code, cause my time is very limited. I’m really sorry for that. Use the code as it is or try to find another source.

      November 3, 2012 at 4:11 pm
  • naghma khan Reply

    Hi
    Mr.Thomas
    this is realy a great articale.

    thanks for the posting

    November 25, 2012 at 12:22 am
  • Prasenjeet Kamble Reply

    thank you so much sir…..
    your code is fabulous !!!

    May 3, 2013 at 10:41 am
  • Timothy Vandeweerd Reply

    Just what I was looking for and it worked perfectly. Thank you so much!

    June 10, 2013 at 9:23 pm
  • Tej Reply

    Hey

    This code was very help full to the project I am workin on right now :)
    but i was wandering if it is possible to add sorting to the same based on what we type in textbox.. I tried a lot of things.. but just doesnt fit into this code !
    can u provide me with any alternative ways to achieve it ??

    July 31, 2013 at 7:54 am
  • Stephane Richard Reply

    This is a very good example of how to create multiple column dropdown combobox. :) it’s fast it’s great code. :) Do you have other such controls you’ve tried to replicate?

    Thanks again.

    February 3, 2014 at 1:10 pm
    • Thomas Claudius Huber Reply

      Hi Stephane,

      thanks for your comment. No, I haven’t tried other controls to replicate. I just needed that one in a web-project.

      Thomas

      February 28, 2014 at 5:10 pm
  • S.Umaa Reply

    hi

    Thanks for your coding. I already tried with your coding but I can’t run.When I copied your coding and ran in my PC,can’t run.So Please tell me any refrence for multiple columns in asp.net drop down list. i want this for my project

    February 13, 2015 at 5:39 am
  • S.Umaa Reply

    plz send the code immediately with step by step explanation as soon as possible

    February 13, 2015 at 11:26 am
    • Thomas Claudius Huber Reply

      Hi Suma,

      the code-link was broken, as I migrated my blog. It works again now.

      February 17, 2015 at 10:56 pm
  • Antonio Reply

    Hi Thomas,
    nice work with this custom control, very easy to connect to a datasource, followed your instructions and it works like a charm!!
    But i do have a question, is it possible to have a single row selected ? Say it is populated with values like 15%, 30%, 50%, etc but you want to preselect 30%?

    I know you time is limited and if you are to busy to answer I understand, but i would be grateful if you could give me some pointers at least.

    Keep up the good work!

    May 15, 2017 at 11:36 pm
  • Dario Corentin Reply

    Thanks this is awesome, Is it possible to make it filterable? on top of firstname lastname have a textbox that filters the results as the user types…Any ideas?

    January 14, 2021 at 10:10 am
    • Thomas Claudius Huber Reply

      Hi Dario, I’m sure it’s possible with Js. But today we can use more modern approaches like Blazor or other SPA frameworks like Angular or React.

      January 20, 2021 at 12:28 pm

Leave a Reply to empee1 Cancel reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.