Aug 28, 2010

Create Dynamic DropDownLists in asp.net

Object:

1. Create dropdownlist dynamically with autopostback property true

2. Keep dropdownlist during postback

3. Maintain selected value during postback.

Here is the sample for this.

In aspx page:


<form id="form1" runat="server">
    <div>
        <asp:Table ID="tbl" runat="server">
        </asp:Table>
        <asp:Button ID="btnSet" runat="server" Text="Button" onclick="btnSet_Click" /> </div>
    </form>
To Create Dynamic Dropdownlist:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    { 
    CreateDynamicTable();
    }
}
    private void CreateDynamicTable()
    {   
        // Fetch the number of Rows and Columns for the table 
        // using the properties
        int tblRows = 3;
        int tblCols = 3;
        // Now iterate through the table and add your controls 
        for (int i = 0; i < tblRows; i++)
        {
            TableRow tr = new TableRow();
            for (int j = 0; j < tblCols; j++)
            {
                TableCell tc = new TableCell();
                DropDownList ddl = new DropDownList();
                ddl.ID = "ddl-" + i.ToString() + "-" + j.ToString();
                for (int k = 0; k < 5; k++)
                {
                    ddl.Items.Add(new ListItem("item-"+k.ToString(),k.ToString()));  
                }
                ddl.AutoPostBack = true;
                ddl.SelectedIndexChanged += new EventHandler(ddl_SelectedIndexChanged);
                // Add the control to the TableCell
                tc.Controls.Add(ddl);
                // Add the TableCell to the TableRow
                tr.Cells.Add(tc);

            }
            // Add the TableRow to the Table
            tbl.Rows.Add(tr);
            tbl.EnableViewState = true;
            ViewState["tbl"] = true;
        }
    }
protected void ddl_SelectedIndexChanged(object sender, EventArgs e)
    { 
    // what you want to perform
    
    }

To retrieve value on button click:


protected void btnSet_Click(object sender, EventArgs e)
    {
        foreach (TableRow tr in tbl.Controls )
        {
            foreach (TableCell tc in tr.Controls)
            {
                if (tc.Controls[0] is DropDownList)
                {
                    Response.Write(((DropDownList)tc.Controls[0]).SelectedItem.Text+" ");         
                }
            }
            Response.Write("<br/>");  
        }
              
    }

Right Now, No output because dynamic controls are lost in postback then what to do.

So we need to save dynamic controls value and generate dynamic controls again.we need to maintain viewstate.


protected override object SaveViewState()
{
    object[] newViewState = new object[2];

    List<string> txtValues = new List<string>();

    foreach (TableRow row in tbl.Controls)
    {
        foreach (TableCell cell in row.Controls)
        {
            if (cell.Controls[0] is DropDownList)
            {
                txtValues.Add(((DropDownList)cell.Controls[0]).SelectedIndex.ToString());
            }
        }
    }

    newViewState[0] = txtValues.ToArray();
    newViewState[1] = base.SaveViewState();
    return newViewState;
}
protected override void LoadViewState(object savedState)
{
    //if we can identify the custom view state as defined in the override for SaveViewState
    if (savedState is object[] && ((object[])savedState).Length == 2 && ((object[])savedState)[0] is string[])
    {
        object[] newViewState = (object[])savedState;
        string[] txtValues = (string[])(newViewState[0]);
        if (txtValues.Length > 0)
        {
            //re-load tables
            CreateDynamicTable();
            int i = 0;
            foreach (TableRow row in tbl.Controls)
            {
                foreach (TableCell cell in row.Controls)
                {
                    if (cell.Controls[0] is DropDownList && i < txtValues.Length)
                    {
                        ((DropDownList)cell.Controls[0]).SelectedIndex = Convert.ToInt32(txtValues[i++]);
                    }
                }
            }
        }
        //load the ViewState normally
        base.LoadViewState(newViewState[1]);
    }
    else
    {
        base.LoadViewState(savedState);
    }
}

Enjoy it.