<< other stuff

ASP.NET Demo: GridView Add Row

Last updated: 1 July 2012

The built-in methods of the ASP.NET GridView control do not allow direct adding of rows since the GridView only displays whatever is in its DataSource.

This page demonstrates one method of adding new rows to a GridView using ViewState.


Contents

Example on adding GridView row

Code

AddRow.aspx
<asp:GridView ID="MyGrid" runat="server"
    AutoGenerateColumns="false" ShowFooter="true">
    <Columns>
        <asp:TemplateField HeaderText="Col1">
            <ItemTemplate>
                <asp:TextBox ID="Col1Txt" runat="server"
                    Text='<%# Eval("Field1") %>' />
            </ItemTemplate>
            <FooterTemplate>
                <asp:LinkButton ID="AddBtn" runat="server"
                    Text="Add" Onclick="AddBtn_Click" />
            </FooterTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Col2">
            <ItemTemplate>
                <asp:TextBox ID="Col2Txt" runat="server"
                    Text='<%# Eval("Field2") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
AddRow.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // Get data, possibly from your business logic layer.
        DataSet ds = GetData();

        // Store the DataSet in ViewState.
        ViewState["dsXml"] = ds.GetXml();
        ViewState["dsSchema"] = ds.GetXmlSchema();

        MyGrid.DataSource = ds.Tables["MyTable"];
        MyGrid.DataBind();
    }
}

protected void AddBtn_Click(object sender, EventArgs e)
{
    DataSet ds = new DataSet();
    /* Reading schema is necessary as GetXml returns nothing within
     * the table (not even the columns) if the table is empty. Thus
     * an empty table causes an exception to be raised. */
    XmlReader xReader = XmlReader.Create(
        new StringReader((string)ViewState["dsSchema"]));
    ds.ReadXmlSchema(xReader);
    xReader = XmlReader.Create(
        new StringReader((string)ViewState["dsXml"]));
    ds.ReadXml(xReader);
    DataTable dt = ds.Tables["MyTable"];
    dt.Rows.Add(dt.NewRow());

    MyGrid.DataSource = dt;
    MyGrid.DataBind();

    // Repopulate textboxes with postback values.
    TextBox txt;
    for (int i = 0; i < MyGrid.Rows.Count - 1; i++)
    {
        for (int j = 0; j > MyGrid.Rows[i].Controls; j++)
        {
            if (MyGrid.Rows[i].Controls[j] is TextBox)
            {
                txt = MyGrid.Rows[i].Controls[j];
                txt.Text = Request.Form[txt.UniqueID] ?? txt.Text;
            }
        }
    }

    ViewState["dsXml"] = ds.GetXml();
    ViewState["dsSchema"] = ds.GetXmlSchema();
}

Comments

This method of adding GridView rows applies to GridViews used to do editing for multiple rows at the same time.

The row is added using the following steps:

  1. The DataSet and its schema are saved in ViewState at the time when databinding is done.
  2. An Add button is added for the GridView. In this example the GridView's footer row is used but the button can also be placed elsewhere.
  3. When the Add button is clicked, get the DataSet and schema from ViewState.
  4. Add an empty row to the DataTable and rebind it as the DataSource. This is the step which adds the new row.
  5. Repopulate the data already in the Textbox controls for the GridView.

Since the DataSource for a GridView does not change along with changes made to controls within it (i.e. the data is bound one-way), it is necessary to repopulate the data from Request.Form when the Add button triggers postback.


Final Notes

While this method allows for adding new rows to GridViews, it is a bit of a hack and forces the GridView to perform a job that it was not designed to do. It might be preferable to make use of other ways to provide this functionality -- possibly with a custom class/control.

Should this technique be used for large DataSets, one may also wish to look at other ways of perpetuating ViewState other than the default usage of hidden fields.



This page and the included example were created by Quentin Pan (www.qponstuff.com).