Dynamically adding and deleting rows from ASP.NET GridView
Introduction
This article talks about a small project that presents the idea of having a
GridView
which facilitate the addition and removal of rows dynamically at run time.
Background
There are many times when we need the user to enter some data but we
are not sure about the amount of data. For instance, we need to have an
application that takes the student details from a faculty
member(possibiliy at the time of admission). We can design this page in
two ways i.e. either we take data of 1 student at a time or we allow the
user to enter data of multiple users in single go. Also we can let the
user choose the number of record he want to enter.
Now to accomplish this if we design the page in such a way that the
user will have the possibility of add adding new rows dynamically and
then enter the data. How can we do that will be the focus of rest of the
article.
Using the code
Let us first design the layout for taking a single record from the user.
Now this design has been achieved by having the template fields in the
Gridview
in the following manner.
Collapse |
Copy Code
<asp:GridView ID="grvStudentDetails" runat="server"
ShowFooter="True" AutoGenerateColumns="False"
CellPadding="4" ForeColor="#333333"
GridLines="None" OnRowDeleting="grvStudentDetails_RowDeleting">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="SNo" />
<asp:TemplateField HeaderText="Student Name">
<ItemTemplate>
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Student Age">
<ItemTemplate>
<asp:TextBox ID="txtAge" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Student Address">
<ItemTemplate>
<asp:TextBox ID="txtAddress" runat="server"
Height="55px" TextMode="MultiLine"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Gender">
<ItemTemplate>
<asp:RadioButtonList ID="RBLGender"
runat="server" RepeatDirection="Horizontal">
<asp:ListItem Value="M">Male</asp:ListItem>
<asp:ListItem Value="F">Female</asp:ListItem>
</asp:RadioButtonList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Qualification">
<ItemTemplate>
<asp:DropDownList ID="drpQualification" runat="server">
<asp:ListItem Value="G">Graduate</asp:ListItem>
<asp:ListItem Value="P">Post Graduate</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>
<asp:CommandField ShowDeleteButton="True" />
</Columns>
<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#EFF3FB" />
<EditRowStyle BackColor="#2461BF" />
<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
<PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
Now the basic idea here is that from code behind if we dynamically change the
DataSource
of this
Gridview
the grid view will change accordingly. So what we will do is that we
will have a single row exposed as default and then keep adding
rows in the
Gridview
whenever the user requests to add a new row. For that we will simply keep adding empty data items
to the
Gridview
adta source resulting in the
Gridview
getting changed dynamically.
Let us see the code to have a default single row
private void FirstGridViewRow()
{
DataTable dt = new DataTable();
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
dt.Columns.Add(new DataColumn("Col1", typeof(string)));
dt.Columns.Add(new DataColumn("Col2", typeof(string)));
dt.Columns.Add(new DataColumn("Col3", typeof(string)));
dt.Columns.Add(new DataColumn("Col4", typeof(string)));
dt.Columns.Add(new DataColumn("Col5", typeof(string)));
dr = dt.NewRow();
dr["RowNumber"] = 1;
dr["Col1"] = string.Empty;
dr["Col2"] = string.Empty;
dr["Col3"] = string.Empty;
dr["Col4"] = string.Empty;
dr["Col5"] = string.Empty;
dt.Rows.Add(dr);
ViewState["CurrentTable"] = dt;
grvStudentDetails.DataSource = dt;
grvStudentDetails.DataBind();
}
The important thing to note in the above code is the use of view state. The
Viewstate
has been kept to facilitate the dynamic addition and deletion of rows
fucntionality. Since we need to preserve the data of rows other than row
being added or deleted we need some place to keep this data. We choose
view state for that.
Now whenever the user choose to add a new row we need to do 2 things,
first we need to add the new row in the grid and secondly we need to
set the data entered in the already added rows.
So to add a new row to the gridview
private void AddNewRow()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
TextBox TextBoxName = (TextBox)grvStudentDetails.Rows[rowIndex].Cells[1].FindControl("txtName");
TextBox TextBoxAge = (TextBox)grvStudentDetails.Rows[rowIndex].Cells[2].FindControl("txtAge");
TextBox TextBoxAddress =
(TextBox)grvStudentDetails.Rows[rowIndex].Cells[3].FindControl("txtAddress");
RadioButtonList RBLGender =
(RadioButtonList)grvStudentDetails.Rows[rowIndex].Cells[4].FindControl("RBLGender");
DropDownList DrpQualification =
(DropDownList)grvStudentDetails.Rows[rowIndex].Cells[5].FindControl("drpQualification");
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = i + 1;
dtCurrentTable.Rows[i - 1]["Col1"] = TextBoxName.Text;
dtCurrentTable.Rows[i - 1]["Col2"] = TextBoxAge.Text;
dtCurrentTable.Rows[i - 1]["Col3"] = TextBoxAddress.Text;
dtCurrentTable.Rows[i - 1]["Col4"] = RBLGender.SelectedValue;
dtCurrentTable.Rows[i - 1]["Col5"] = DrpQualification.SelectedValue;
rowIndex++;
}
dtCurrentTable.Rows.Add(drCurrentRow);
ViewState["CurrentTable"] = dtCurrentTable;
grvStudentDetails.DataSource = dtCurrentTable;
grvStudentDetails.DataBind();
}
}
else
{
Response.Write("ViewState is null");
}
SetPreviousData();
}
And to set the previoduly entered data
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 TextBoxName = (TextBox)grvStudentDetails.Rows[rowIndex].Cells[1].FindControl("txtName");
TextBox TextBoxAge = (TextBox)grvStudentDetails.Rows[rowIndex].Cells[2].FindControl("txtAge");
TextBox TextBoxAddress = (TextBox)grvStudentDetails.Rows[rowIndex].Cells[3].FindControl("txtAddress");
RadioButtonList RBLGender = (RadioButtonList)grvStudentDetails.Rows[rowIndex].Cells[4].FindControl("RBLGender");
DropDownList DrpQualification = (DropDownList)grvStudentDetails.Rows[rowIndex].Cells[5].FindControl("drpQualification");
TextBoxName.Text = dt.Rows[i]["Col1"].ToString();
TextBoxAge.Text = dt.Rows[i]["Col2"].ToString();
TextBoxAddress.Text = dt.Rows[i]["Col3"].ToString();
RBLGender.SelectedValue = dt.Rows[i]["Col4"].ToString();
DrpQualification.SelectedValue = dt.Rows[i]["Col5"].ToString();
rowIndex++;
}
}
}
}
Now the similar stuff needs to be done when the user will choose to
delete the row. We need to delete the row user selected and then we need
to set the data of previous rows
To delete the row selected
protected void grvStudentDetails_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
SetRowData();
if (ViewState["CurrentTable"] != null)
{
DataTable dt = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
int rowIndex = Convert.ToInt32(e.RowIndex);
if (dt.Rows.Count > 1)
{
dt.Rows.Remove(dt.Rows[rowIndex]);
drCurrentRow = dt.NewRow();
ViewState["CurrentTable"] = dt;
grvStudentDetails.DataSource = dt;
grvStudentDetails.DataBind();
for (int i = 0; i < grvStudentDetails.Rows.Count - 1; i++)
{
grvStudentDetails.Rows[i].Cells[0].Text = Convert.ToString(i + 1);
}
SetPreviousData();
}
}
}
And then to reset the data in other rows
private void SetRowData()
{
int rowIndex = 0;
if (ViewState["CurrentTable"] != null)
{
DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
DataRow drCurrentRow = null;
if (dtCurrentTable.Rows.Count > 0)
{
for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
{
TextBox TextBoxName = (TextBox)grvStudentDetails.Rows[rowIndex].Cells[1].FindControl("txtName");
TextBox TextBoxAge = (TextBox)grvStudentDetails.Rows[rowIndex].Cells[2].FindControl("txtAge");
TextBox TextBoxAddress = (TextBox)grvStudentDetails.Rows[rowIndex].Cells[3].FindControl("txtAddress");
RadioButtonList RBLGender = (RadioButtonList)grvStudentDetails.Rows[rowIndex].Cells[4].FindControl("RBLGender");
DropDownList DrpQualification = (DropDownList)grvStudentDetails.Rows[rowIndex].Cells[5].FindControl("drpQualification");
drCurrentRow = dtCurrentTable.NewRow();
drCurrentRow["RowNumber"] = i + 1;
dtCurrentTable.Rows[i - 1]["Col1"] = TextBoxName.Text;
dtCurrentTable.Rows[i - 1]["Col2"] = TextBoxAge.Text;
dtCurrentTable.Rows[i - 1]["Col3"] = TextBoxAddress.Text;
dtCurrentTable.Rows[i - 1]["Col4"] = RBLGender.SelectedValue;
dtCurrentTable.Rows[i - 1]["Col5"] = DrpQualification.SelectedValue;
rowIndex++;
}
ViewState["CurrentTable"] = dtCurrentTable;
}
}
else
{
Response.Write("ViewState is null");
}
}
Now when we run the application we can see that we can safely add and remove the rows dynamically to this
Gridview
Note:
The sample application is in full working condition. Running the
application and debugging it(steping through it is highly advisable to
understand the logic fully and get the jizt of whats happening inside