In this article I will explain how to create dynamic DropDownList control in asp.net. I will also explain how to retain value across postbacks and also how to recreate the controls on each postback. In addition I will explain how to dynamically attach event handlers to DropDownList control in asp.net


Dynamic DropDownList control in asp.net



To start with I added a PreInit event to the Page and added the following snippet in it

C#

Panel pnlDropDownList;

protected void Page_PreInit(object sender, EventArgs e)

{

    //Create a Dynamic Panel

    pnlDropDownList = new Panel();

    pnlDropDownList.ID = "pnlDropDownList";

    pnlDropDownList.BorderWidth = 1;

    pnlDropDownList.Width = 300;

    this.form1.Controls.Add(pnlDropDownList);

 

    //Create a LinkDynamic Button to Add TextBoxes

    LinkButton btnAddDdl = new LinkButton();

    btnAddDdl.ID = "btnAddDdl";

    btnAddDdl.Text = "Add DropDownList";

    btnAddDdl.Click += new System.EventHandler(btnAdd_Click);

    this.form1.Controls.Add(btnAddDdl);

   

    //Recreate Controls

    RecreateControls("ddlDynamic", "DropDownList");

}

 

VB.Net

Private pnlDropDownList As Panel

Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreInit   'Create a Dynamic Panel

   pnlDropDownList = New Panel()

   pnlDropDownList.ID = "pnlDropDownList"

   pnlDropDownList.BorderWidth = 1

   pnlDropDownList.Width = 300

   Me.form1.Controls.Add(pnlDropDownList)

 

   'Create a LinkDynamic Button to Add TextBoxes

   Dim btnAddDdl As New LinkButton()

   btnAddDdl.ID = "btnAddDdl"

   btnAddDdl.Text = "Add DropDownList"

   AddHandler btnAddDdl.Click, AddressOf btnAdd_Click

   Me.form1.Controls.Add(btnAddDdl)

 

   'Recreate Controls

   RecreateControls("ddlDynamic", "DropDownList")

End Sub


As you will notice above I have created the following controls

 1 Dynamic panel pnlDropDownList and added it to the form control on the page

2. Dynamic LinkButton btnAddDdl attached a Click event btnAdd_Click to it and added to the form control.

3. A function called RecreateControls is being called which I’ll explain later in the article

 

On the Click event of the dynamic LinkButton I have added the following event


C#

protected void btnAdd_Click(object sender, EventArgs e)

{

    int cnt = FindOccurence("ddlDynamic");

    CreateDropDownList("ddlDynamic-" + Convert.ToString(cnt + 1));

}

 

VB.Net

Protected Sub btnAdd_Click(ByVal sender As Object, ByVal e As EventArgs)

    Dim cnt As Integer = FindOccurence("ddlDynamic")

    CreateDropDownList("ddlDynamic-" & Convert.ToString(cnt + 1))

End Sub

 

As you will notice I am calling two functions

1. FindOccurence

2. CreateDropDownList

 

The FindOccurence function as the name suggests gets the occurrence of the Dynamic DropDownList in the Request.Form collection. The basic idea is that I have given ID is a common pattern that is all IDs are of the form txtDynamic e.g. txtDynamic-1, txtDynamic-2 and so on.

 

C#

private int FindOccurence(string substr)

{

    string reqstr = Request.Form.ToString();

    return ((reqstr.Length - reqstr.Replace(substr, "").Length)

                      / substr.Length);

}


VB.Net

Private Function FindOccurence(ByVal substr As String) As Integer

   Dim reqstr As String = Request.Form.ToString()

   Return ((reqstr.Length - reqstr.Replace(substr, "").Length) & _

                                           / substr.Length)

End Function

 

Now the CreateDropDownList as the name suggests is used to create dynamic DropDownList. The function accepts ID as parameter

C#

private void CreateDropDownList(string ID)

{

    DropDownList ddl = new DropDownList();

    ddl.ID = ID;

    ddl.Items.Add(new ListItem("--Select--", ""));

    ddl.Items.Add(new ListItem("One", "1"));

    ddl.Items.Add(new ListItem("Two", "2"));

    ddl.Items.Add(new ListItem("Three", "3"));

    ddl.AutoPostBack = true;

    ddl.SelectedIndexChanged += new EventHandler(OnSelectedIndexChanged);

    pnlDropDownList.Controls.Add(ddl);

 

    Literal lt = new Literal();

    lt.Text = "<br />";

    pnlDropDownList.Controls.Add(lt);

}

 


VB.Net

Private Sub CreateDropDownList(ByVal ID As String)

   Dim ddl As New DropDownList()

   ddl.ID = ID

   ddl.Items.Add(New ListItem("--Select--", ""))

   ddl.Items.Add(New ListItem("One", "1"))

   ddl.Items.Add(New ListItem("Two", "2"))

   ddl.Items.Add(New ListItem("Three", "3"))

   ddl.AutoPostBack = True

   AddHandler ddl.SelectedIndexChanged, AddressOf OnSelectedIndexChanged

   pnlDropDownList.Controls.Add(ddl)

 

   Dim lt As New Literal()

   lt.Text = "<br />"

   pnlDropDownList.Controls.Add(lt)

End Sub



As you will notice I am creating a new DropDownList and adding Items to it. Once done that I am attaching SelectedIndexChanged Event Handler and setting the AutoPostBack property to true. Finally I am adding it to the panel pnlDropDownList.

   

The SelectedIndexChanged Event Handler is given below.

C#

protected void OnSelectedIndexChanged(object sender, EventArgs e)

{

    DropDownList ddl = (DropDownList)sender;

    string ID = ddl.ID;

    ClientScript.RegisterClientScriptBlock(this.GetType(), "Alert",

                 "<script type = 'text/javascript'>alert('" + ID  +

                  " fired SelectedIndexChanged event');</script>");

   

    //Place the functionality here

}


VB.Net

Protected Sub OnSelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)

    Dim ddl As DropDownList = DirectCast(sender, DropDownList)

    Dim ID As String = ddl.ID

 

    'Place the functionality here

    ClientScript.RegisterClientScriptBlock(Me.GetType(), _

    "Alert", "<script type = 'text/javascript'>alert('" & ID _

    & " fired SelectedIndexChanged event');</script>")

End Sub

 



ID of the DropDownList that caused the postback on selected index changed event

 

Now the most important function is RecreateControls whose job is to recreate all the DropDownList on each postback

C#

private void RecreateControls(string ctrlPrefix, string ctrlType)

{

    string[] ctrls = Request.Form.ToString().Split('&');

    int cnt = FindOccurence(ctrlPrefix);

    if (cnt > 0)

    {

        for (int k = 1; k <= cnt; k++)

        {

            for (int i = 0; i < ctrls.Length; i++)

            {

                if (ctrls[i].Contains(ctrlPrefix + "-" + k.ToString())

                    && !ctrls[i].Contains("EVENTTARGET"))

                {

                    string ctrlID = ctrls[i].Split('=')[0];

 

                    if (ctrlType == "DropDownList")

                    {

                        CreateDropDownList(ctrlID);

                    }

                    break;

                }

            }

        }

    }

}

 

  VB.Net

Private Sub RecreateControls(ByVal ctrlPrefix As String, ByVal ctrlType As String)

  Dim ctrls As String() = Request.Form.ToString().Split("&"c)

  Dim cnt As Integer = FindOccurence(ctrlPrefix)

  If cnt > 0 Then

      For k As Integer = 1 To cnt

         For i As Integer = 0 To ctrls.Length - 1

             If ctrls(i).Contains((ctrlPrefix & "-") + k.ToString()) _

                  AndAlso Not ctrls(i).Contains("EVENTTARGET") Then

                 Dim ctrlID As String = ctrls(i).Split("="c)(0)

 

                 If ctrlType = "DropDownList" Then

                      CreateDropDownList(ctrlID)

                 End If

                 Exit For

             End If

         Next

     Next

  End If

End Sub

 

As you will notice above I first find the occurrence of a particular string here ddlDynamic in the Request.Form collection and then I loop through each item and keep adding the DropDownList using the CreateDropDownList function described earlier.

One important thing I need to point out which people overlook is always give unique IDs to dynamic controls when you create them

This completes the article download the sample code in VB.Net and C# using the link below

Download Code (4.13 kb)