Reputation: 19071
I am using C# .NET 2.0 Visual Studio 2005.
I am encountering weird issue.
There is a simple window form with just one DataGridView with column1 being checkbox (DataGridViewCheckboxColumn).
Then if the checkbox in the cell is checked, I want to remove the checked row.
Sound really simple but it does not remove all checked rows somehow, and I can't really figure why it is behaving in this way.
For instance, I have 5 rows and checked all checkbox in each row but it only removes 3 rows. Has anyone seen this before? Is this a bug or am I doing something wrong?
namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//when I click the button, all checked row should be removed
private void button1_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if ((bool)row.Cells[0].Value)
{
dataGridView1.Rows.Remove(row);
}
}
}
}
}
Upvotes: 8
Views: 31717
Reputation: 739
protected void btnDelRow_Click(object sender, EventArgs e)
{
#region Delete Row from data list Grid On Behalf of checkbox from dyanamically added grid
int ClSno = 0; /*Use For Sitewise New Serial No*/
foreach (DataListItem dst in dstBillDetails.Items)
{
ClSno = ClSno + 1;
Label lbl_SChkFlag = (Label)dst.FindControl("lblSChkFlag");
GridView Grid_B = (GridView)dst.FindControl("GridB");
if (lbl_SChkFlag.Text == "0")
{
int Newbillflg = 0;/**If SiteCode Is Zero Then Usefull**/
foreach (GridViewRow gvr in Grid_B.Rows)
{
#region
Label lbl_grdId = (Label)gvr.FindControl("lblgrdId");
CheckBox chk_dstgrdlst = (CheckBox)gvr.FindControl("chkdstgrdlst");
if (chk_dstgrdlst.Checked == true)
{
if (Grid_B.Rows.Count > 1)
{
gvr.Style["display"] = "none";
lbl_grdId.Text = "1";
}
else
{/**When Gridview Row is Zero**/
Grid_B.Visible = false;
lbl_grdId.Text = "1";
/**When Gridview Row is Zero**/
}
}
#endregion
}
}
}
#endregion
}
Upvotes: 0
Reputation: 1
ASPXPAGE:
<strong>Asp.Net : Delete Multiple Records form datagridview in one time<br />
</strong>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
BackColor="White" BorderColor="#CCCCCC" BorderStyle="None" BorderWidth="1px"
CellPadding="4" EnableModelValidation="True" ForeColor="Black">
<Columns>
<asp:TemplateField>
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="id" HeaderText="Sr No" />
<asp:BoundField DataField="doc_name" HeaderText="Name" />
<asp:BoundField DataField="doc_add" HeaderText="Address" />
<asp:BoundField DataField="doc_mob" HeaderText="Mobile No" />
<asp:BoundField DataField="doc_email" HeaderText="Email" />
</Columns>
<FooterStyle BackColor="#CCCC99" ForeColor="Black" />
<HeaderStyle BackColor="#333333" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="White" ForeColor="Black" HorizontalAlign="Right" />
<SelectedRowStyle BackColor="#CC3333" Font-Bold="True" ForeColor="White" />
</asp:GridView>
<br />
<asp:Button ID="Button1" runat="server" Font-Size="12pt"
onclick="Button1_Click1" Text="Delete" />
<br />
Code Behind Page:
SqlConnection conn = new SqlConnection(@"server=server-pc; database=HMS; integrated security=true");
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack == false)
{
load_data();
}
}
public void load_data()
{
SqlDataAdapter adp = new SqlDataAdapter("select * from doc_master", conn);
DataSet ds = new DataSet();
adp.Fill(ds);
GridView1.DataSource = ds.Tables[0];
GridView1.DataBind();
}
protected void Button1_Click1(object sender, EventArgs e)
{
CheckBox ch;
for (int i = 0; i < GridView1.Rows.Count; i++)
{
ch = (CheckBox)GridView1.Rows[i].Cells[0].Controls[1];
if (ch.Checked == true)
{
int id = Convert.ToInt32(GridView1.Rows[i].Cells[1].Text);
SqlCommand cmd = new SqlCommand("delete from doc_master where ID=" + id + " ", conn);
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}
}
load_data();
}
For detailed code visit: http://www.gtuguide.com/2014/05/deleting-multiple-rows-in-gridview.html
Upvotes: 0
Reputation: 21
this solution gives a little error, I fixed adding 1 line :)
List<DataGridViewRow> toDelete = new List<DataGridViewRow>();
foreach (DataGridViewRow row in dataGridView1.Rows)
{
bool s = Convert.ToBoolean(row.Cells[0].Value) //added this line
if (s == true)
{
toDelete.Add(row);
}
}
foreach (DataGridViewRow row in toDelete)
{
dataGridView1.Rows.Remove(row);
}
Upvotes: 2
Reputation: 4839
You are modifying a collection while iterating it. Try like this
List<DataGridViewRow> toDelete = new List<DataGridViewRow>();
foreach (DataGridViewRow row in dataGridView1.Rows) {
if (row.Cells[0].Value == true) {
toDelete.Add(row);
}
}
foreach (DataGridViewRow row in toDelete) {
dataGridView1.Rows.Remove(row);
}
Upvotes: 6
Reputation: 1830
its happening when one row is removed the rows count decrements too so if you put your code in for loop and run it in reverse it would work fine have a look:
for (int i = dataGridView1.Rows.Count -1; i >= 0 ; i--)
{
if ((bool)dataGridView1.Rows[i].Cells[0].FormattedValue)
{
dataGridView1.Rows.RemoveAt(i);
}
}
Upvotes: 14
Reputation: 2764
@Chen Kinnrot, is absolutely on the money! You will always only delete n % 2 rows when you run your function, so if you have 10 rows, then you would delete 5, and 101 would be 51, etc. Iterate over the collection to find which checkboxes are check and then remove those rows. The better solution would be to attach an event to the checkbox that automatically runs when you click button1.
Upvotes: 1
Reputation: 21015
You are modifiend a collection while iterating it.
Use a delete list and than remove the rows.
Upvotes: 6