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.