How to Delete a Row from Gridview

GridView Delete Row

Found the solution, only needed to do a databound.... Here is the working code:

    else if (e.CommandName == "Delete")
{
int index = Convert.ToInt32(e.CommandArgument);
GridView1.DeleteRow(index);
((DataTable)ViewState["DataTable"]).Rows[index].Delete();
((DataTable)ViewState["DataTable"]).AcceptChanges();
GridView1.DataSource = (DataTable)ViewState["Data"];
GridView1.DataBind();
}

How to delete a row from GridView?

You are deleting the row from the gridview but you are then going and calling databind again which is just refreshing the gridview to the same state that the original datasource is in.

Either remove it from the datasource and then databind, or databind and remove it from the gridview without redatabinding.

Remove Row from GridView

First thing you should note is you are deleting the row from grid not from the data table
Then you again bind the data table which may not give you any change, What you should do is instead of deleting from grid delete it from datatable

Rewrite it like

      if (e.CommandName == "Delete")
{
if (!string.IsNullOrEmpty(e.CommandArgument.ToString()))
{
int rowIndex = Convert.ToInt32(e.CommandArgument);
DataTable table = CreateDataTable(false, string.Empty, string.Empty);
table.Rows.RemoveAt(rowIndex)
grdSelectedProducts.DataSource = table;
grdSelectedProducts.DataBind();
}
}

If you need it to remove it from DB , DOnt forget to do that , And also note that the above code each time when u fetch the table it will give u everything from DB
so you can make it global , or you can just remove from DB

Delete a row in Gridview

I'd recommend you to work with the bound data while adding/deleting rows, not with the rows directly since you've chosen grid view. Code is much simpler then.
Below is an example - note that I initialize there DataTable in a static scope (which is not a perfect place) - store it where you need - in memory/session, or in view state - depends on your task there.

public partial class WebForm4 : System.Web.UI.Page
{

private static DataTable MyDataTable = new DataTable();

static WebForm4()
{
MyDataTable.Columns.Add("sno");
MyDataTable.Columns.Add("name");
}
private void AddNewRow()
{
MyDataTable.Rows.Add(MyDataTable.NewRow());
GridView1.DataSource = MyDataTable;
GridView1.DataBind();
}

protected void Button1_Click(object sender, EventArgs e)
{
AddNewRow();
}

protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
MyDataTable.Rows.RemoveAt(e.RowIndex);
GridView1.DataSource = MyDataTable;
GridView1.DataBind();
}
}

Hope that helped.

delete row in Gridview after databind()

It will be good if you remove that particular row from your DataTable first and then bind to gridview as shown below:

for (int i = 0; i < dtUser.Rows.Count; i++)
{
//check
if(dtUser.Rows[i]["DataKeyName"].ToString()) == yourValue))
{
//remove
dtUser.Rows.Remove(dtUser.Rows[i]);
break;
}
}

then

dummyGridview.DataSource = dtUser;
dummyGridview.DataBind();

Hope It solves your purpose.

I'm deleting rows from gridview but all data in the table is deleted

Well, we are deleting one row at a time, right?

Ok, based on feedback, need/want this for the markup:

 <asp:GridView ID="Gridview1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Header 2">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("Column1") %>' ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 3">
<ItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Eval("Column2") %>' ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 4">
<ItemTemplate>
<asp:TextBox ID="TextBox3" runat="server" Text='<%# Eval("Column3") %>' ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete" ItemStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:Button ID="cmdDel" runat="server" Text="Delete" OnClick="cmdDel_Click"
OnClientClick="return confirm('Delete this row? (cannot undo)');"/>
</ItemTemplate>
</asp:TemplateField>

</Columns>
</asp:GridView>
<br />

<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row" OnClick="ButtonAdd_Click" />

<asp:Button ID="cmdSave" runat="server" Text="Save Grid to Table" Style="margin-left:30px" OnClick="cmdSave_Click"/>

And the code looks like:

    DataTable dt = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CreateTable();
AddRow();
LoadGrid();
ViewState["MyTable"] = dt;
}
else
{
dt = (DataTable)ViewState["MyTable"];
}
}

void CreateTable()
{
dt.Columns.Add(new DataColumn("RowNumber", typeof(int)));
dt.Columns[0].AutoIncrementSeed = 1;
dt.Columns[0].AutoIncrementStep = 1;
dt.Columns[0].AutoIncrement = true;

dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dt.Columns.Add(new DataColumn("Column3", typeof(string)));
}

void AddRow()
{
DataRow dr = dt.NewRow();
dr["Column1"] = "";
dr["Column2"] = "";
dr["Column3"] = "";
dt.Rows.Add(dr);
}

void LoadGrid()
{
// Gridview1.Columns.Clear();
Gridview1.DataSource = dt;
Gridview1.DataBind();
}

protected void ButtonAdd_Click(object sender, EventArgs e)
{
SaveData();
AddRow();
LoadGrid();
}

void SaveData()
{
// move grid changes back to table
foreach (GridViewRow gvRow in Gridview1.Rows)
{
//extract the TextBox values
DataRow dr = dt.Rows[gvRow.RowIndex];
dr["Column1"] = ((TextBox)gvRow.FindControl("TextBox1")).Text;
dr["Column2"] = ((TextBox)gvRow.FindControl("TextBox2")).Text;
dr["Column3"] = ((TextBox)gvRow.FindControl("TextBox3")).Text;
}
dt.AcceptChanges();
}

protected void cmdSave_Click(object sender, EventArgs e)
{
SaveData();
}

protected void cmdDel_Click(object sender, EventArgs e)
{
Button cmdDel = (Button)sender;
GridViewRow gvRow = (GridViewRow)cmdDel.Parent.Parent;

dt.Rows[gvRow.RowIndex].Delete();
dt.AcceptChanges();
LoadGrid();
}

Of course the save button in real use would be "submit" and move on to the next web page, or whatever task the user is working on.

And I assume this is just for learning, since a table just sitting in memory has next to zero use. I would assume that the table would be from a database, else this setup not all that much use.

Add and Delete Rows From ASP.NET GridView

Not at all clear why you have all that extra code in add row????

If you want to default values, why not take them from the persisted datatable, and why bother with the grid??? - I don't think you need all that code.

Now, to make this really work? You do want a extra routine - Grid to table.

but, lets leave that for now.

2nd, note that because data table is a object, once you point the object to viewstate, then changes ALSO point back to view state (you don't have to re-save back into viewstate. With a string, or int counter - yes you do, but not with objects (since then you only really working with a pointer to the given object).

Also, don't bother with the built in GV delete button - it really is more pain then it is worth. Just drop in a button into the GV, and wrire up a click event. That way you don't have to mess with the row data bound event to shove in the client side confirm you have.

Also, for most grids, you don't need to show/display/include/have the row ID. In fact for reasons of secuirty, in most cases I don't display the database PK row id (and you don't have to).

And one more FYI: When you start to add a LOT of custom controls to a grid view? Well, it always painful that each custom control needs that template tags. And with quite a few controls, that becomes really messy fast. So, I suggest a ListView, as each custom control dropped into the ListView does not requite those template tags. But, lets leave this tip for next around around.

Also, MANY do not realize that you can send a whole datatalbe BACK to the database if the datatable came from a database, and can execute this save back WITH ONE command that will automatic write back all updates, inserts and even deletes. Of course in your example, we just playing and building a 100% in-memory data table, but this whole setup works near the same if/when the datatable was from a database.

So, I would dump the built in delete button.

I would dump the row data bound code.

I also would consider moving the add button OUT of the GV. You can turn on "ShowHeaderWhenEmpty" = true. that will THEN display the header - even without data. But without data, the footer DOES NOT show, and thus if you delete the one row, you be unable to add that row.

So, our markup is this:

NOTE close, I did not want to write code to load up each row - we don't have to, so note how I added the Text = expression. Again, less code.

<asp:GridView ID="Gridview1" runat="server" ShowFooter="true" 
AutoGenerateColumns="false" CssClass="table"
ShowHeaderWhenEmpty="true" Datakeys="RowNumber" >
<Columns>
<asp:BoundField DataField="RowNumber" HeaderText="Row Number" />
<asp:TemplateField HeaderText="Header 1">
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Eval("Column1") %>' ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 2">
<ItemTemplate>
<asp:TextBox ID="TextBox2" runat="server" Text='<%# Eval("Column2") %>' ></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Header 3">
<ItemTemplate>
<asp:TextBox ID="TextBox3" runat="server" Text='<%# Eval("Column3") %>' ></asp:TextBox>
</ItemTemplate>
<FooterStyle HorizontalAlign="Right" />
<FooterTemplate>
<asp:Button ID="ButtonAdd" runat="server" Text="Add New Row"
OnClick="ButtonAdd_Click" cssclass="btn"/>
</FooterTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText ="Delete">
<ItemTemplate>
<asp:Button ID="cmdDelete" runat="server" Text="Delete" CssClass="btn"
OnClick="cmdDelete_Click"
OnClientClick = '<%# "return confirm(\"Really delete this row " +
Container.DisplayIndex + " (" +
Eval("RowNumber") + ")" + "\");" %>'
/>
</ItemTemplate>
</asp:TemplateField>

</Columns>
</asp:GridView>

And HOW you start the page up? Beyond important!!!

So, we have this code:

   DataTable dt = new DataTable();
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
SetInitialRow();
else
dt = ViewState["CurrentTable"] as DataTable;
}

private void SetInitialRow()
{
DataRow dr = null;
dt.Columns.Add(new DataColumn("RowNumber", typeof(int)));
dt.Columns[0].AutoIncrement = true;
//Set the Starting or Seed value.
dt.Columns[0].AutoIncrementSeed = 1;
//Set the Increment value.
dt.Columns[0].AutoIncrementStep = 1;

dt.Columns.Add(new DataColumn("Column1", typeof(string)));
dt.Columns.Add(new DataColumn("Column2", typeof(string)));
dt.Columns.Add(new DataColumn("Column3", typeof(string)));

dr = dt.NewRow();
dr["RowNumber"] = 1;
dr["Column1"] = string.Empty;
dr["Column2"] = string.Empty;
dr["Column3"] = string.Empty;
dt.Rows.Add(dr);

ViewState["CurrentTable"] = dt;

Gridview1.DataSource = dt;
Gridview1.DataBind();
}

Note how I moved the table to class level.

Now code to add is this:

    protected void ButtonAdd_Click(object sender, EventArgs e)
{
GridToTable();

DataRow MyNewRow = dt.NewRow();
dt.Rows.Add(MyNewRow);
Gridview1.DataSource = dt;
Gridview1.DataBind();
}

And code to delete is this:

    protected void cmdDelete_Click(object sender, EventArgs e)
{
GridToTable();

Button cmdDel = sender as Button;
GridViewRow gRow = cmdDel.NamingContainer as GridViewRow;

// get row to delete

int RowDel = gRow.RowIndex;

dt.Rows[RowDel].Delete();
Gridview1.DataSource = dt;
Gridview1.DataBind();
}

So, as noted, above quite much makes this work. As noted, if we are to allow editing of the data (assume yes), then we need one more routine that moves grid back to data.

So, when you hit a save button, we call GridToTable.

So, when you hit a add button, we call Grid to Table.

So, when you hit delete button, we call Grid to table.

In other words, we REALLY need to save all edits BACK to the table before we add, or delete or even want to save the table to a database.

So, we need this routine:

    void GridToTable()
{
// send current grid back to table.
foreach (GridViewRow gRow in Gridview1.Rows)
{
DataRow OneRow = dt.Rows[gRow.RowIndex];

OneRow["Column1"] = (gRow.FindControl("TextBox1") as TextBox).Text;
OneRow["Column2"] = (gRow.FindControl("TextBox2") as TextBox).Text;
OneRow["Column3"] = (gRow.FindControl("TextBox3") as TextBox).Text;
}
}

Gridview Add/delete rows

You can use the approach in code below for this. In the addRow method shown, a new grid row is inserted. The logic is that we need to re-bind the grid to a new data source that contains the original rows plus a new empty row. You can use a similar approach for delete ( create a new data source with deleted rows excluded and then rebind the grid).

When deleting use the method deleteRow. I have assumed that you have a check box control with an id of chkDelete in the grid row, which when checked would mean the row needs to be deleted. You can delete multiple rows at the same time using the method of deleteRow.

If you use the below two methods for adding a row and deleting row(s) then automatically your edited text boxes would have their new values retained always i.e. editing would then be automatically taken care of.

Assumptions made : Also, I have assumed that there are 3 text boxes in grid row in addition to a check box. Because there are 3 textboxes, so the DataTable being created in methods below should contain 3 columns for these 3 textboxes and these columns should be of string type.

Add a Row

protected void addRow()
{
DataTable dt = new DataTable();
//add code to create columns for this data table
//only create columns for textbox data
dt.Columns.Add("Column1", typeof(string));
dt.Columns.Add("Column2", typeof(string));
dt.Columns.Add("Column3", typeof(string));
DataRow dr = null;

//build a data source of existing rows
foreach (GridViewRow gridRow in grid1.Rows)
{
dr = dt.NewRow();

//set only text box values in new data source
//so checkbox column for row selection will be ignored
TextBox txtColumn1 = gridRow.FindControl("txtColumn1") as TextBox;
TextBox txtColumn2 = gridRow.FindControl("txtColumn2") as TextBox;
TextBox txtColumn3 = gridRow.FindControl("txtColumn3") as TextBox;

dr[0] = txtColumn1.Text;
dr[1] = txtColumn2.Text;
dr[2] = txtColumn3.Text;

dt.Rows.Add(dr);
}

//create the row in data sourec for the new grid row
dr = dt.NewRow();
dt.Rows.Add(dr);

//bind the grid view, which will now show you the new added row in addition to original rows
grd.DataSource = dt;
grd.DataBind();
}

Delete Row(s)

protected void deleteRow()
{
DataTable dt = new DataTable();
//add code to create column for this data table
//only set column for textbox columns
dt.Columns.Add("Column1", typeof(string));
dt.Columns.Add("Column2", typeof(string));
dt.Columns.Add("Column3", typeof(string));

//build a data source of existing rows
foreach (GridViewRow gridRow in grid1.Rows)
{
//get whether the checkbox for deleting row is checked or not
CheckBox chkDelete = gridRow.FindControl("chkDelete") as CheckBox;
//do not add original row if it was checked to be deleted
if(!chkDelete.Checked)
{
dr = dt.NewRow();

//set only text box values in new data source
//so checkbox column for row selection will be ignored
TextBox txtColumn1 = gridRow.FindControl("txtColumn1") as TextBox;
TextBox txtColumn2 = gridRow.FindControl("txtColumn2") as TextBox;
TextBox txtColumn3 = gridRow.FindControl("txtColumn3") as TextBox;

dr[0] = txtColumn1.Text;
dr[1] = txtColumn2.Text;
dr[2] = txtColumn3.Text;

dt.Rows.Add(dr);
}
}

//bind the grid view, which will now NOT have the deleted rows
grd.DataSource = dt;
grd.DataBind();
}


Related Topics



Leave a reply



Submit