Dynamic GridView rows in ASP.NET

Here's a simple proof-of-concept for dynamically adding and removing rows in an ASP.NET GridView control while maintaining the existing data. The ViewState is used to maintain the information between postbacks. The rehydrate_table function takes advantage of this to rebuild the table anew whenever an event takes place.

Default.aspx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="utf=8" />  
    <title>Dynamic GridView</title>  
</head>  
<body>  
    <form id="form1" runat="server">  
        <div>  
            <p>  
            <asp:Button ID="btnAddRow" runat="server" OnClick="btnAddRow_Click" Text="Add Row" CausesValidation="false" />  
            </p>  
            <asp:GridView ID="gvTable" runat="server" AutoGenerateColumns="false" OnRowDeleting="gvTable_RowDeleting">  
                <Columns>  
                    <asp:TemplateField HeaderText="Name">  
                        <ItemTemplate>  
                            <asp:TextBox ID="txtName" runat="server" Text='<%# Eval("name") %>' />  
                        </ItemTemplate>  
                    </asp:TemplateField>  
                    <asp:TemplateField HeaderText="Age">  
                        <ItemTemplate>  
                            <asp:TextBox ID="txtAge" runat="server" Text='<%# Eval("age") %>' />  
                        </ItemTemplate>  
                    </asp:TemplateField>  
                    <asp:CommandField ButtonType="Link" ShowDeleteButton="true" />  
                </Columns>  
            </asp:GridView>  
        </div>  
    </form>  
</body>  
</html>

Default.aspx.cs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using System;  
using System.Data;  
using System.Web.UI;  
using System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page  
{  
    protected void Page_Load(object sender, EventArgs e)  
    {  
        if (!IsPostBack)  {  
            var tbl = new DataTable();  
            tbl.Columns.Add("name");  
            tbl.Columns.Add("age");  
            tbl.Rows.Add(tbl.NewRow());  
            ViewState["table"] = tbl;  
            gvTable.DataSource = tbl;  
            gvTable.DataBind();  
        }  
    }

    private void rehydrate_table()  
    {  
        if (ViewState["table"] == null) return;  
        var dt = (DataTable)ViewState["table"];  
        if (dt.Rows.Count == 0) return;

        for (int i = 0; i < dt.Rows.Count; i++)  
        {  
            var name = ((TextBox)gvTable.Rows[i].Cells[0].FindControl("txtName"));  
            dt.Rows[i]["name"] = name.Text;  
            var age = ((TextBox)gvTable.Rows[i].Cells[1].FindControl("txtAge"));  
            dt.Rows[i]["age"] = age.Text;  
        }  
    }

    protected void btnAddRow_Click(object sender, EventArgs e)  
    {  
        rehydrate_table();  
        var tbl = (DataTable)ViewState["table"];  
        tbl.Rows.Add(tbl.NewRow());  
        gvTable.DataSource = tbl;  
        gvTable.DataBind();  
        ViewState["table"] = tbl;  
    }

    protected void gvTable_RowDeleting(object sender, GridViewDeleteEventArgs e)  
    {  
        rehydrate_table();  
        var tbl = (DataTable)ViewState["table"];  
        tbl.Rows.RemoveAt(e.RowIndex);  
        gvTable.DataSource = tbl;  
        gvTable.DataBind();  
        ViewState["table"] = tbl;  
    }  
}

Comments !