Few months ago I wrote a sample demo on how to Add Dynamic Rows in GridView with TextBoxes and how to Add Dynamic Rows in GridView with DropDownLists.  I have had a few comments and emails asking how to do the same with a combination of TextBox and DropDownList. In this post, I'm going to show you the way on how to this.

Here are the code blocks below:

ASPX:  

<asp:gridview ID="Gridview1"  runat="server"  ShowFooter="true"
                              AutoGenerateColumns="false">
        <Columns>
        <asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
        <asp:TemplateField HeaderText="Header 1">
            <ItemTemplate>
                <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Header 2">
            <ItemTemplate>
                <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField  HeaderText="Header 3">
            <ItemTemplate>
                <asp:DropDownList ID="DropDownList1" runat="server"
                                  AppendDataBoundItems="true">
                     <asp:ListItem Value="-1">Select</asp:ListItem>
                </asp:DropDownList>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Header 4">
            <ItemTemplate>
                <asp:DropDownList ID="DropDownList2" runat="server"
                                  AppendDataBoundItems="true">
                     <asp:ListItem Value="-1">Select</asp:ListItem>
                </asp:DropDownList>
            </ItemTemplate>
            <FooterStyle HorizontalAlign="Right" />
            <FooterTemplate>
                 <asp:Button ID="ButtonAdd" runat="server" 
                             Text="Add New Row" 
                             onclick="ButtonAdd_Click" />
            </FooterTemplate>
        </asp:TemplateField>
        </Columns>
</asp:gridview> 

As you can see from the markup above, I have set up a BoundField for displaying the RowNumber and some Template Field columns so that GridView will automatically generate a row of TextBox and DropDownLists when adding a new row.You will also notice that I have added a Button Control under the FooterTemplate at the last column in the GridView.

Note: Since we are added a Control in the GridView footer, then be sure to set ShowFooter to TRUE in the GridView.

CODE BEHIND:

Again, just like in my previous example,We are going to populate the DropDownLists on the fly. Note that I am using a dummy data and stored it in the ArrayList just for the simplicity of this demo. 

public partial class GridDemo : System.Web.UI.Page 
{ 
        private ArrayList GetDummyData() { 

            ArrayList arr = new ArrayList(); 

            arr.Add(new ListItem("Item1", "1")); 
            arr.Add(new ListItem("Item2", "2")); 
            arr.Add(new ListItem("Item3", "3")); 
            arr.Add(new ListItem("Item4", "4")); 
            arr.Add(new ListItem("Item5", "5")); 

            return arr; 
        } 

        private void FillDropDownList(DropDownList ddl) { 
            ArrayList arr = GetDummyData(); 

            foreach (ListItem item in arr) { 
                ddl.Items.Add(item); 
            } 
        } 

        private void SetInitialRow() { 

            DataTable dt = new DataTable(); 
            DataRow dr = null; 

            dt.Columns.Add(new DataColumn("RowNumber", typeof(string))); 
            dt.Columns.Add(new DataColumn("Column1", typeof(string)));//for TextBox value 
            dt.Columns.Add(new DataColumn("Column2", typeof(string)));//for TextBox value 
            dt.Columns.Add(new DataColumn("Column3", typeof(string)));//for DropDownList selected item 
            dt.Columns.Add(new DataColumn("Column4", typeof(string)));//for DropDownList selected item 

            dr = dt.NewRow(); 
            dr["RowNumber"] = 1; 
            dr["Column1"] = string.Empty; 
            dr["Column2"] = string.Empty; 
            dt.Rows.Add(dr); 

            //Store the DataTable in ViewState for future reference 

            ViewState["CurrentTable"] = dt; 

            //Bind the Gridview 
            Gridview1.DataSource = dt; 
            Gridview1.DataBind(); 

           //After binding the gridview, we can then extract and fill the DropDownList with Data 

            DropDownList ddl1 = (DropDownList)Gridview1.Rows[0].Cells[3].FindControl("DropDownList1"); 
            DropDownList ddl2 = (DropDownList)Gridview1.Rows[0].Cells[4].FindControl("DropDownList2"); 
            FillDropDownList(ddl1); 
            FillDropDownList(ddl2); 
        } 

        private void AddNewRowToGrid() { 

            if (ViewState["CurrentTable"] != null) { 

                DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"]; 
                DataRow drCurrentRow = null; 

                if (dtCurrentTable.Rows.Count > 0) { 
                    drCurrentRow = dtCurrentTable.NewRow(); 
                    drCurrentRow["RowNumber"] = dtCurrentTable.Rows.Count + 1; 

                    //add new row to DataTable 
                    dtCurrentTable.Rows.Add(drCurrentRow); 
                    //Store the current data to ViewState for future reference 

                    ViewState["CurrentTable"] = dtCurrentTable; 


                    for (int i = 0; i < dtCurrentTable.Rows.Count - 1; i++) { 

                        //extract the TextBox values 

                        TextBox box1 = (TextBox)Gridview1.Rows[i].Cells[1].FindControl("TextBox1"); 
                        TextBox box2 = (TextBox)Gridview1.Rows[i].Cells[2].FindControl("TextBox2"); 

                        dtCurrentTable.Rows[i]["Column1"] = box1.Text; 
                        dtCurrentTable.Rows[i]["Column2"] = box2.Text; 

                       //extract the DropDownList Selected Items 

                        DropDownList ddl1 = (DropDownList)Gridview1.Rows[i].Cells[3].FindControl("DropDownList1"); 
                        DropDownList ddl2 = (DropDownList)Gridview1.Rows[i].Cells[4].FindControl("DropDownList2"); 

                        // Update the DataRow with the DDL Selected Items 

                        dtCurrentTable.Rows[i]["Column3"] = ddl1.SelectedItem.Text; 
                        dtCurrentTable.Rows[i]["Column4"] = ddl2.SelectedItem.Text; 

                    } 

                    //Rebind the Grid with the current data to reflect changes 
                    Gridview1.DataSource = dtCurrentTable; 
                    Gridview1.DataBind(); 
                } 
            } 
            else { 
                Response.Write("ViewState is null"); 

            } 
            //Set Previous Data on Postbacks 
            SetPreviousData(); 
        } 

        private void SetPreviousData() { 

            int rowIndex = 0; 
            if (ViewState["CurrentTable"] != null) { 

                DataTable dt = (DataTable)ViewState["CurrentTable"]; 
                if (dt.Rows.Count > 0) { 

                    for (int i = 0; i < dt.Rows.Count; i++) { 

                        TextBox box1 = (TextBox)Gridview1.Rows[i].Cells[1].FindControl("TextBox1"); 
                        TextBox box2 = (TextBox)Gridview1.Rows[i].Cells[2].FindControl("TextBox2"); 

                        DropDownList ddl1 = (DropDownList)Gridview1.Rows[rowIndex].Cells[3].FindControl("DropDownList1"); 
                        DropDownList ddl2 = (DropDownList)Gridview1.Rows[rowIndex].Cells[4].FindControl("DropDownList2"); 

                        //Fill the DropDownList with Data 
                        FillDropDownList(ddl1); 
                        FillDropDownList(ddl2); 

                        if (i < dt.Rows.Count - 1) { 

                           //Assign the value from DataTable to the TextBox 
                            box1.Text = dt.Rows[i]["Column1"].ToString(); 
                            box2.Text = dt.Rows[i]["Column2"].ToString(); 

                            //Set the Previous Selected Items on Each DropDownList  on Postbacks 
                            ddl1.ClearSelection(); 
                            ddl1.Items.FindByText(dt.Rows[i]["Column3"].ToString()).Selected = true; 

                            ddl2.ClearSelection(); 
                            ddl2.Items.FindByText(dt.Rows[i]["Column4"].ToString()).Selected = true; 

                        } 

                        rowIndex++; 
                    } 
                } 
            } 
        } 

        protected void Page_Load(object sender, EventArgs e) { 
            if (!Page.IsPostBack) { 
                SetInitialRow(); 
            } 
        } 

        protected void ButtonAdd_Click(object sender, EventArgs e) { 
            AddNewRowToGrid(); 
        } 
}

Method Definitions:

GetDummyData()

A method that returns an ArrayList. Basically this method contains a static dummy data for populating the DropDownList.

FillDropDownList(DropDownList ddl)

A method that fills the DropDownList with the dummy data.

SetInitialRow()

A method that binds the GridView on initial load with a single row of data. The DataTable defined in this method is stored in ViewState so that it can be referenced anywhere in the codes when it postbacks. Basically this table will serve as the original DataSource for the GridView.

AddNewRowToGrid()

A method that adds a new row to the GridView when a Button is clicked and store the newly added row values in the Original Table that was defined in the SetInitialRow() method.

SetPreviousData()

A method that retains all the items that was selected from the DropDownList when it postbacks.


The output would look something like below when you run it on the browser:

On Initial Load:

 

After Adding some Rows:

 

That's it! I hope someone find this useful.