Implementing Cascading DropDownList in ASP.NET GridView

Posted by: Suprotim Agarwal , on 10/27/2008, in Category ASP.NET
Views: 175299
Abstract: I wrote this article sometime ago in response to a query asked by a dotnetcurry.com viewer. The user had a requirement where he had two dropdownlist in the GridView and the second one was to be populated at runtime based on the selected value of the first dropdownlist – A case of cascading dropdownlists.
Implementing Cascading DropDownList in ASP.NET GridView
 
I wrote this article sometime ago in response to a query asked by a dotnetcurry.com viewer. The user had a requirement where he had two dropdownlist in the GridView and the second one was to be populated at runtime based on the selected value of the first dropdownlist – A case of cascading dropdownlists.
Here’s an approach I followed without using a single line of code. We will be using the Categories and Products table of the Northwind database to show the cascading effect.
Viewers, who have prior experience in configuring the SqlDataSource, can jump directly to Step 5:
Step 1: Open VS 2008. Click File > New > Website. Choose ASP.NET Website from the list of installed template, choose target platform as .NET Framework 3.5, choose the desired language and enter the location where you would like to store the website on your FileSystem. I have created a folder called VS2008 Projects, so the location over here is C:\VS2008 Projects\ CascadingDropDownInGridView. After typing the location, click OK.
Step 2: Open Default.aspx. Switch to the Design mode of Default.aspx. Open the toolbox (Ctrl+Alt+X) > Data Tab > Drag and drop a SqlDataSource control on to the form. Click on the smart tag or right click SqlDataSource > Show Smart Tag > ‘Configure Data Source’ wizard. Click on ‘New Connection’ to open the ‘Add Connection’. Type your ‘Server Name’ and ‘Select a database Name’ to connect to. Over here, I have used (local) as the ‘ServerName’ and the database I am connecting to, is Northwind. Click on ‘Test Connection’ to make sure that there are no errors while connecting to the server. Click Ok.
Step 3: In the ‘Configure Data Source’, click ‘Next’. An option will be displayed to save the connection string to the configuration file. Select the checkbox ‘Yes, save this connection as:’, type a name for the connectionstring ‘NorthwindConnectionString’ and click Next.
Step 4: In the ‘Configure Select Statement’ > select ‘Specify Columns from Tables or Views’ radiobutton > Select ‘Categories’ table in the Name and choose CategoryID, CateogoryName as columns. Click Next > ‘Test Query’ to preview data > click Finish. The wizard adds a SqlDataSource control to the page as shown below.
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]">           
</asp:SqlDataSource>
If you check your web.config, the connection string is added as shown below:
<connectionStrings>
      <add name="NorthwindConnectionString" connectionString="Data Source=(local);Initial Catalog=Northwind;Integrated Security=True" providerName="System.Data.SqlClient"/>
</connectionStrings>
Step 5: Now add a GridView control to the page. We will add a BoundField and a TemplateField to display the CategoryID and CategoryName’s respectively. The TemplateField will contain our first dropdownlist displaying CategoryNames.
<form id="form1" runat="server">
<div>
 
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]">           
</asp:SqlDataSource>
 
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="CategoryID" DataSourceID="SqlDataSource1">          
<Columns>             
    <asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
        InsertVisible="False" ReadOnly="True" SortExpression="CategoryID" />  
        
    <asp:TemplateField HeaderText="Categories">       
        <ItemTemplate>                  
            <asp:DropDownList ID="ddlCategories" AutoPostBack="true"
            DataTextField="CategoryName" DataValueField="CategoryID"
            DataSourceID="SqlDataSource1" runat="server" AppendDataBoundItems="true"
            SelectedValue='<%# Bind("CategoryID") %>' />
       </ItemTemplate>
    </asp:TemplateField>
 
 
</Columns>
</asp:GridView>
 
</div>
</form>
Note: The SelectedValue='<%# Bind("CategoryID") %>' helps us select the CategoryName in the dropdownlist in accordance with the CategoryID, when the page is first loaded.
Step 6: So far so good. We now have to add the second dropdownlist whose values will be determined at runtime depending on the value selected in the first dropdownlist. In our case, when the user will select CategoryName in the first dropdown, corresponding Products will be displayed in the second dropdown.
Add another Template Field (with a second dropdownlist) in the GridView as well as one more SqlDataSource. This time the SqlDataSource2 will be bound to the ‘Products’ table. Moreover, the ‘SelectCommand’ of the SqlDataSource will accept a parameter, which will be the selected category. Let us see the markup for the same:
<asp:TemplateField HeaderText="Products">       
        <ItemTemplate> 
            <asp:DropDownList ID="ddlProducts"
            DataTextField="ProductName" DataValueField="ProductID"
            DataSourceID="SqlDataSource2" runat="server" />
            <asp:SqlDataSource runat="server" ID="sqlDataSource2"
               ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
                SelectCommand="SELECT [ProductID], [ProductName], CategoryID FROM [Products]" FilterExpression="CategoryID = '{0}'">
                <FilterParameters>
                <asp:ControlParameter Name="categoryParam" ControlID="ddlCategories"
                     PropertyName="SelectedValue" />
                </FilterParameters>                       
            </asp:SqlDataSource>
         </ItemTemplate>
    </asp:TemplateField>     
Notice the <FilterParameters> element used as a child of the SqlDataSource2. This element is worth observing over here. The <FilterParameters> is a very handy feature of the SqlDataSource control especially when you have a requirement of filtering the results of a query based on a value that is known only at run time. So without making another roundtrip to the server, you can filter out the data that is made available by the SqlDataSource. All you have to do is to create filter expressions that contains parameter placeholders. So for each filter parameter placeholder, you use a parameter element.
In our case, we have created a filter parameter that gets its value from a DropDownList control.
Well that’s all the markup that is required to create cascading dropdownlist in a gridview. Run the application and you can now test the functionality of populating the second dropdownlist based on the selected value of the first dropdownlist. The application will look similar to the image below:
Cascading DDL
The entire markup is as shown below:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!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>Cascading DropDownList In GridView</title>
</head>
<body>
<form id="form1" runat="server">
<div>
 
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
SelectCommand="SELECT [CategoryID], [CategoryName] FROM [Categories]">           
</asp:SqlDataSource>
 
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="CategoryID" DataSourceID="SqlDataSource1">          
<Columns>             
    <asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
        InsertVisible="False" ReadOnly="True" SortExpression="CategoryID" />  
        
    <asp:TemplateField HeaderText="Categories">       
        <ItemTemplate>                  
            <asp:DropDownList ID="ddlCategories" AutoPostBack="true"
            DataTextField="CategoryName" DataValueField="CategoryID"
            DataSourceID="SqlDataSource1" runat="server" AppendDataBoundItems="true"
            SelectedValue='<%# Bind("CategoryID") %>' />
       </ItemTemplate>
    </asp:TemplateField>
       
    <asp:TemplateField HeaderText="Products">       
        <ItemTemplate> 
            <asp:DropDownList ID="ddlProducts"
            DataTextField="ProductName" DataValueField="ProductID"
            DataSourceID="SqlDataSource2" runat="server" />
            <asp:SqlDataSource runat="server" ID="sqlDataSource2"
               ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
                SelectCommand="SELECT [ProductID], [ProductName], CategoryID FROM [Products]"
                FilterExpression="CategoryID = '{0}'">
                <FilterParameters>
                <asp:ControlParameter Name="categoryParam" ControlID="ddlCategories"
                     PropertyName="SelectedValue" />
                </FilterParameters>                       
            </asp:SqlDataSource>
         </ItemTemplate>
    </asp:TemplateField>     
 
</Columns>
</asp:GridView>
 
</div>
</form>
</body>
</html>
 
 
I hope this article was useful and I thank you for viewing it.
If you liked the article,  Subscribe to my RSS Feed.

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for Sixteen consecutive years. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that offers Digital Marketing and Branding services to businesses, both in a start-up and enterprise environment.

Get in touch with him on Twitter @suprotimagarwal or at LinkedIn



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Thanigainathan.S on Saturday, November 15, 2008 10:26 AM
Hi,
This is really a nice idea .I appreciate your idea.
Thanks
Comment posted by Farha on Sunday, November 16, 2008 1:59 PM
May I call you a savior........
Comment posted by Sujith PV on Monday, November 17, 2008 4:34 AM
Hi

This is very nice artilce.

Regards
Sujith PV
Comment posted by Pawan on Monday, November 17, 2008 5:46 AM
i LIKE yOUR sITE, gOOD wORK
http://dev.codeplatter.com
A forum for the developers-by the developers
Comment posted by Mikhail on Monday, November 17, 2008 12:02 PM
I would probably add update panel around the grid or change it to use webservice and javascript based update to avoid refreshing the page each time.
Comment posted by LV on Monday, November 17, 2008 4:25 PM
Thanks for a great articles, keep it up.  Cheers!
Comment posted by Suprotim Agarwal on Tuesday, November 18, 2008 4:54 AM
Mikhail: Yes you can wrap the sample around an UpdatePanel. That's what makes it so easy to ajaxify your apps using the UpdatePanel.
Comment posted by aaa on Tuesday, November 18, 2008 12:10 PM
Good approach but it is not really useful without the capability to do update.
Comment posted by ABHI on Friday, November 21, 2008 6:41 AM
Very use full article.
Thank You so much.
Comment posted by Hamid Reza on Tuesday, December 16, 2008 3:15 PM
that's was nice,
but how can implement edit function on this GridView (with these two related DropDownlists)
Comment posted by Hamid Reza on Wednesday, December 17, 2008 3:42 AM
that's was nice,
but how can implement edit function on this GridView (with these two related DropDownlists)
Comment posted by smondal on Wednesday, January 14, 2009 5:39 AM
very nice :-)
Comment posted by ppp on Tuesday, January 27, 2009 6:28 AM
ok good ya i will follow your details
Comment posted by gita on Thursday, February 26, 2009 8:02 AM
how to new record in grid?



Comment posted by Bart on Monday, March 2, 2009 4:57 AM
indeed, not very usefull if the update doesn't work
Comment posted by shamsher ali on Friday, March 13, 2009 7:52 AM
haw we can implement dropdownlist with its selectindexchanged event e.g. if we select empId of and emp table then all regarding information should be desplayed in the textbox like empname empsalary etc.
please sent mail thank you
Comment posted by houssein on Sunday, May 3, 2009 8:18 AM
hello,

10x for this solution, it really helped.
only 1 question, i am using it in a grid view in edit mode, when i press edit i need the filtered drop down default value to be the current value of row grid, any idea ? when i data bound, i got this error: Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.

help plz
Comment posted by Suprotim Agarwal on Monday, May 4, 2009 12:05 AM
houssein: Check if this helps - http://aspadvice.com/blogs/joteke/archive/2008/08/24/Is-_2200_Databinding-methods-such-as-Eval_280029002C00_-XPath_280029002C00_-and-Bind_28002900_-can-only-be-used-in-the-context-of-a-databound-control_2E002200_-causing-you-grief_3F00_.aspx
Comment posted by Haneen Daoud on Wednesday, July 8, 2009 8:36 AM
I don't have "selected value' property in the drop down list in Grid view .. it doesn't apear
Comment posted by surendra singh on Thursday, October 8, 2009 1:15 AM
hello,
         Thanks for this solution.This web site is realy very helpful for begginers and professional.Very good thing of this site is that it describe all needful topics in full details in the form of steps...
I realy impressed with this site and i will suggest to my friends to use this site for help...

Thank  you very much for this site
Comment posted by David on Thursday, October 22, 2009 1:57 PM
it doesn't make sense at all for using dropdownlist in the  readonly Gridview , by the way, this way doesn't work on the edit mode at all... worthless.
Comment posted by LOL!! on Tuesday, November 3, 2009 7:23 PM
readonly gridview dropdowns??  Exactly, doesn't make sense!!!!
Comment posted by shoeb on Friday, November 6, 2009 5:14 AM
i want to learn about all control of asp.net
Comment posted by sylvia on Saturday, February 27, 2010 3:32 PM
this is too good. thanks. helped me solve a whole load of problems with dropdowns in gridview
Comment posted by Rajeev on Tuesday, April 20, 2010 2:52 PM
regarding
Note: The SelectedValue='<%# Bind("CategoryID") %>' helps us select the CategoryName in the dropdownlist in accordance with the CategoryID, when the page is first loaded.

when I added it , it gives error that selectedvalue can't be set declaratively.
Comment posted by 800 Pilot on Tuesday, May 25, 2010 8:59 PM
Has anyone figured out how to retain the selected value of dropodownlist2 when a user selects edit?  That would be handy information to have.

Thanks!
Comment posted by sumesh gaud on Tuesday, August 10, 2010 1:53 AM
yah afcoarse thats very good presentation.
Comment posted by SK on Saturday, October 30, 2010 11:00 AM
How to find out drop down list ID with master pages in mark up?  I am trying to achieve same functionality into Detailview but got error that couldn't find ddlCategory.

Thank you.
Comment posted by SK on Saturday, October 30, 2010 11:00 AM
How to find out drop down list ID with master pages in mark up?  I am trying to achieve same functionality into Detailview but got error that couldn't find ddlCategory.

Thank you.
Comment posted by rhiena on Sunday, January 16, 2011 1:12 PM
hii, i have tryed your tutorial, but when i finished updating, the data can't change,why?i use linq datasource,
i need your help, please confirm to my email...
Comment posted by Irfan Ranjha on Wednesday, May 4, 2011 10:45 AM
Hi,
i liked the code, can you please help me, im trying to develop same page but dont want to use code behind, i want to write whole code in sqlDataSource plz advise.
Comment posted by Manasi S on Monday, May 9, 2011 5:57 AM
Thanks a lot your article is very useful..
Comment posted by umuntu on Wednesday, June 1, 2011 5:12 AM
cheers...just to the point!!!
Comment posted by Madiha on Monday, July 11, 2011 9:45 AM
Can I do the same thing in WIndows form application instead of Asp.Net Website ?
Comment posted by Chirag Rathod on Wednesday, September 14, 2011 6:20 AM
Hi,
I Bind Gridview with 4 BoundFields And Other All Colums In Templatefield. In TemplateField I Use Itemtemplate for Dropdownlist. But I can't get the selected value of dropdownlist. So,Please Help me for that.
My Code For Bind Gridview is shown Below.

DataTable dt = new DataTable();

        dt.Columns.Add("FirstName");
        dt.Columns.Add("LastName");
        dt.Columns.Add("Age", typeof(System.Int32));

        DataRow oItem = dt.NewRow();
        oItem[0] = "Shawpnendu";
        oItem[1] = "Bikash";
        oItem[2] = 32;
        dt.Rows.Add(oItem);

        oItem = dt.NewRow();
        oItem[0] = "Bimalendu";
        oItem[1] = "Bikash";
        oItem[2] = 27;
        dt.Rows.Add(oItem);
        ViewState["dttable"] = dt;



        GridView gv = new GridView();
        gv.AutoGenerateColumns = false;

        BoundField nameColumn = new BoundField();
        nameColumn.DataField = "FirstName";
        nameColumn.HeaderText = "First Name";
        gv.Columns.Add(nameColumn);

        nameColumn = new BoundField();
        nameColumn.DataField = "LastName";
        nameColumn.HeaderText = "Last Name";
        gv.Columns.Add(nameColumn);

        nameColumn = new BoundField();
        nameColumn.DataField = "Age";
        nameColumn.HeaderText = "Age";
        gv.Columns.Add(nameColumn);

        // Here is template column portion
        TemplateField TmpCol = new TemplateField();
        TmpCol.HeaderText = "Click Me";
        gv.Columns.Add(TmpCol);
        TmpCol.ItemTemplate = new TemplateHandler();

        TemplateField TmpCol1 = new TemplateField();
        TmpCol1.HeaderText = "Click Me1";
        gv.Columns.Add(TmpCol1);
        TmpCol1.ItemTemplate = new TemplateHandler();

        gv.DataSource = dt;
        gv.DataBind();

        Form.Controls.Add(gv);
    }
    public class TemplateHandler : ITemplate
    {
        void ITemplate.InstantiateIn(Control container)
        {
            //Button cmd = new Button();
            //cmd.ID = "cmd";
            //cmd.Text = "HI";
            //cmd.Click += new EventHandler(Dynamic_Method);
            //container.Controls.Add(cmd);

            DropDownList ddl = new DropDownList();
            // ddl.ID = "ddl";
            ddl.Items.Add("Chirag");
            ddl.Items.Add("Patel");
            ddl.SelectedIndexChanged += new EventHandler(ddl_SelectedIndexChanged);
            //TextBox ddl = new TextBox();
            container.Controls.Add(ddl);
        }

        void ddl_SelectedIndexChanged(object sender, EventArgs e)
        {
            string abc;
            abc = sender.ToString();
        }

        
    }
Comment posted by akd on Thursday, January 12, 2012 9:31 AM
but how your are going to do the same during run time.
because you always need to configure the connection string from web config.
Ok my point is how u r going to do the same with DataTable or DatSet.
Comment posted by karthik on Friday, October 5, 2012 10:24 AM
hai ur post is very useful to me..
can u give code for this scenario suppose we have two dropdownlist A(outside the gridview) and B((outside the gridview)) and a gridview within that gridview we have two dropdownlist C and D comparing this dropdownlist A and B our C(within gridview) and D(within gridview) dropdownlist should populate watever selecting in dropdownlist C should not listed in dropdownlist D
Comment posted by hk on Monday, January 14, 2013 1:14 PM
Suprotim,

How can i make it working without hard coding connection string and SQL statement in markup? Can i achieve this through code behind?

Thank you!
Comment posted by Marlon on Tuesday, March 12, 2013 9:17 AM
Hi Suprotim,

You're a Lifesaver.

Thanks so much

Greetings from Colombia
Comment posted by mahesh on Saturday, July 20, 2013 7:02 AM
hi

can you post the same project that is using data binding to dropdownlist and gridview with coding in .cs file
Comment posted by Harshit Mehta on Monday, July 7, 2014 12:44 AM
Hi Suprotim ,

I wanted to ask you this:

Suppose there is 1 gridview. Inside this gridview, we have 2 dropdownlists.

Now, is it possible to change the index of second dropdown based on the index of first dropdown?

I want to do this using JavaScript only.
Comment posted by Todd Z on Tuesday, July 22, 2014 6:15 PM
You are my hero...thank you so much!!