在DataGridView(表格)中删除多行

4
我有一个名为"myTable"的数据表,它与一个名为"dgv"的DataGridView绑定。DataGridView "dgv"有一列复选框。我的目标是在按钮事件中删除选中的行。当然,数据表会被更新。 现在我的代码只能删除一行,而不能删除多行。
谢谢帮助。
 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);
        }
    }

你是否遇到了异常?我猜测当你移除第一行时,foreach应该会产生异常,因为集合已经被改变了。 - Ivan Ičin
没有任何异常。看起来它没有循环遍历。 - user1108948
尝试将此代码移出 foreach 循环:myTable.Rows.Remove(dataRow); - Ivan Ičin
我不这么认为,它只会删除一行,并且可能会出现异常,因为dataRow是在foreach循环内定义的。 - user1108948
哦,抱歉,复制和粘贴错了,我想的是这一行代码:dgv.DataSource = myTable; - Ivan Ičin
显示剩余3条评论
4个回答

1

我找到了解决方案。错误是由...引起的。

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

currentDataRowView 不是被选中的行。

正确的代码是:

                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()); 

感谢大家的帮助。


0
你尝试过使用索引循环而不是 foreach 吗?我认为 CurrentRow 可能在每次迭代时没有更新。
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);
            } 

你选择了这一行,但是你移除它了吗?我看到你注释掉了移除的那一行。 - user1108948
@Love 谢谢...忘记我把它们注释掉了。 - Josh

0

看起来你只是从DataGridView中获取了CurrentRow,而不是在foreach循环中获取当前行。此外,你正在修改正在迭代的集合。这可能会起作用:

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);
    }
}

您的表已经绑定到GridView,无需重新绑定。只需从DataTable中删除DataRows即可。 - ScottieMc
toDelete列表保存了您的DataTable中所有“已选中”的行。一旦您从列表中删除了已选中的DataRows,它们就会从GridView中删除,因为GridView绑定到了DataTable上。这可能不是最优雅的解决方案,但我相信它有效。 - ScottieMc
但是如何删除 toDelete 中的行呢?你是不是想说 foreach(DataRow dr in myTable.Rows) { if (toDelete.Contains(dr)) myTable.Rows.Remove(dr);}? - user1108948
它只删除了最后一行。 - user1108948
抱歉,我的声望不够,否则我会和你聊天的。你有遇到任何异常吗? - ScottieMc
显示剩余5条评论

0
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();
   }

如需详细代码,请访问: http://www.gtuguide.com/2014/05/deleting-multiple-rows-in-gridview.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接