title: Remove Row from GridView
body: <p>I have a grid view on my page and I want to allow the user to add / remove items to it.  How it works, and the add functionality does work albeit probably not great, is that a user selects a product from a drop down list, then clicks Add.  </p>
  
  <p>This creates a new row in grid with the select Product text and ID.   The <code>GridView</code> markup is:</p>
  
  <pre><code>                            &lt;asp:GridView runat="server" ID="grdSelectedProducts" BorderWidth="1px" CellPadding="3" CellSpacing="2" AutoGenerateColumns="False" OnRowDataBound="grdSelectedProducts_OnRowDataBound" ShowHeaderWhenEmpty="True" DataKeyNames="ProductId"
                                  OnRowCommand="grdSelectedProducts_RowCommand" OnRowDeleted="grdSelectedProducts_RowDeleted" OnRowDeleting="grdSelectedProducts_RowDeleting"&gt;
                                  &lt;Columns&gt;
                                      &lt;asp:BoundField DataField="Product" HeaderText="Product" ReadOnly="False" /&gt;
                                      &lt;asp:TemplateField&gt;
                                          &lt;ItemTemplate&gt;
                                              &lt;asp:LinkButton runat="server" ID="linkDelete" runat="server" CommandName="Delete" CommandArgument="&lt;%# Container.DataItemIndex %&gt;"&gt;Remove&lt;/asp:LinkButton&gt;
                                          &lt;/ItemTemplate&gt;
                                      &lt;/asp:TemplateField&gt;
                                      &lt;asp:BoundField DataField="ProductId" HeaderText="ProductId" ReadOnly="False" Visible="False" /&gt;
                                  &lt;/Columns&gt;
                              &lt;/asp:GridView&gt;
  </code></pre>
  
  <p>The data in the grid is bound but there is no connection to a database, as it's just the information from the drop down.</p>
  
  <p>The <code>linkDelete</code> is where I want to allow the user to remove an item, so my question is, how can I actually delete the row?  I've got the <code>RowCommand</code> event up which I've tried to remove it, but it just doesn't seem to work correctly as the table either 1) gets rebound with the same data as before or 2) all rows are removed due to the binding of a new <code>DataTable</code>.  I'm missing something obvious, but this type of grid is new to me.</p>
  
  <p>Any example I've seen here or on Google has been around gridviews which are databound from SQL, or some other database, which seems to make the rebinding easier.  However my version doesn't use that so binding again doesn't seem to work correctly.</p>
  
  <pre><code>    protected void grdSelectedProducts_RowCommand(object sender, GridViewCommandEventArgs e)
      {
          if (e.CommandName == "Delete")
          {
              if (!string.IsNullOrEmpty(e.CommandArgument.ToString()))
              {
                  int rowIndex = Convert.ToInt32(e.CommandArgument);
                  grdSelectedProducts.DeleteRow(rowIndex);
                  CountryDataTable = (DataTable)grdSelectedProducts.DataSource;
                  DataTable table = CreateDataTable(false, string.Empty, string.Empty);
                  grdSelectedProducts.DataSource = table;
                  grdSelectedProducts.DataBind();
              }
          }
      }
  
  
      private DataTable CreateDataTable(bool isAddingValue, string selectedProduct, string selectedId)
      {
          // if isAddingValue is FALSE then it isn't from a button click to add a Product, it is just
          // a call to create the datatable
  
          DataTable dataTable = ProductDataTable;
          if (!dataTable.Columns.Contains("Product"))
          {
              dataTable.Columns.Add("Product");
              dataTable.Columns.Add("ProductId");
          }
  
          if (isAddingValue)
          {
              // Get the data from ViewState
              DataRow dataRow;
              dataRow = dataTable.NewRow();
              dataRow["Product"] = selectedProduct;
              dataRow["ProductId"] = selectedId;
              dataTable.Rows.Add(dataRow);
          }
          else
          {
              grdSelectedProducts.DataSource = null;
              grdSelectedProducts.DataSource = ProductDataTable;
              grdSelectedProducts.DataBind();
          }
  
          // Save the data back to ViewState
          ProductDataTable = dataTable;
  
          return dataTable;
      }
  
      private DataTable ProductDataTable
      {
          get {return ViewState["ProductDataTable"] as DataTable ?? new DataTable(); }
          set { ViewState["ProductDataTable"] = value; }
      }
  </code></pre>
  
  <p>I do have the <code>RowDeleting</code> &amp; <code>RowDeleted</code> events but I don't have any code in it.</p>