简体   繁体   中英

Delete multiple rows in a DataGridView(table)

I have a datable "myTable", which is bind with a DataGridView "dgv". The DataGridView "dgv" has a checkbox column. My goal is to delete rows checked in a button event. The datatable is updated of course. Now my code is only working for deleting one row not for multiple rows.

Thanks for help.

 private void btnDel_Click(object sender, EventArgs e)
    {
        try
        {
            if (dgv.RowCount>0)
            {
                foreach (DataGridViewRow row in dgv.Rows)
                {
                    DataGridViewCheckBoxCell check = row.Cells[0] as DataGridViewCheckBoxCell;
                    if (check.Value != null)
                    {
                        if ((bool)check.Value)
                        {
                            DataRowView currentDataRowView = (DataRowView)dgv.CurrentRow.DataBoundItem;
                            DataRow dataRow = currentDataRowView.Row;

                            int n = dgv.CurrentRow.Index;
                            int intID = Convert.ToInt32(dgv.Rows[n].Cells[0].Value);
                            myTable.Rows.Remove(dataRow);
                            dgv.DataSource = myTable;

                            Int32 intVal = Convert.ToInt32(row.Cells[1].Value);
                            if (intVal == intID)
                            {
                                check.Value = null;
                            }
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

I found the solution. The error was caused by

 DataRowView currentDataRowView = (DataRowView)dgv.CurrentRow.DataBoundItem; 

currentDataRowView is not the checked row. The correct code is:

                List<DataRow> toDelete = new List<DataRow>(); 
                for (int i = 0; i < dgv.Rows.Count; i++)
                {
                    {
                        DataGridViewRow row = dgv.Rows[i];
                        DataGridViewCheckBoxCell check = row.Cells[0] as DataGridViewCheckBoxCell;
                        if (check.Value != null && (bool)check.Value)
                        {
                            DataRow dataRow = (row.DataBoundItem as DataRowView).Row;
                            toDelete.Add(dataRow);
                        }
                    }
                }
                toDelete.ForEach(row => row.Delete()); 

Thanks everybody's help.

Have you tried iterating by index instead of by a foreach? I think the CurrentRow may not be updating per each iterationg:

try {
                if (dgv.RowCount > 0) {
                    for (int i = 0; i < dgv.Rows.Count;i++ ) {
                        DataGridViewRow row = dgv.Rows[i];
                        DataGridViewCheckBoxCell check = row.Cells[0] as DataGridViewCheckBoxCell;
                        if (check.Value != null) {
                            if ((bool)check.Value) {
                                dgv.Rows[i].Selected = true;
                                dgv.Rows[i].Cells[0].Selected = true;
                                DataRowView currentDataRowView = (DataRowView)dgv.CurrentRow.DataBoundItem;
                                DataRow dataRow = currentDataRowView.Row;

                                int n = dgv.CurrentRow.Index;
                                int intID = Convert.ToInt32(dgv.Rows[n].Cells[0].Value);
                                myTable.Rows.Remove(dataRow);
                                dgv.DataSource = myTable;

                                Int32 intVal = Convert.ToInt32(row.Cells[1].Value);
                                if (intVal == intID) {
                                    check.Value = null;
                                }
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                MessageBox.Show(ex.Message);
            } 

It looks like you're only grabbing the CurrentRow from your DataGridView instead of the current row in your foreach loop. Also you are modifying the collection you are iterating through. This might work:

private void btnDel_Click(object sender, EventArgs e)
{
    try
    {
        List<DataRow> toDelete = new List<DataRow>();
        foreach (DataGridViewRow row in dgv.Rows)
        {
            DataGridViewCheckBoxCell check = row.Cells[0] as DataGridViewCheckBoxCell;
            if (check.Value != null && (bool)check.Value)
              toDelete.Add(((DataRowView)row.DataBoundItem).Row);
        }

        toDelete.ForEach(row => row.Delete());
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}
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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM