如何删除选定的 DataGridViewRow 并更新已连接的数据库表?

Posted

技术标签:

【中文标题】如何删除选定的 DataGridViewRow 并更新已连接的数据库表?【英文标题】:How to delete a selected DataGridViewRow and update a connected database table? 【发布时间】:2011-01-06 06:16:12 【问题描述】:

我在 Windows 窗体应用程序(用 C# 编写)上有一个 DataGridView 控件。

我需要的是:当用户选择 DataGridViewRow,然后单击“删除”按钮时,应该删除该行并且接下来,需要使用表适配器更新数据库。

这是我目前所拥有的:

private void btnDelete_Click(object sender, EventArgs e)

    if (this.dataGridView1.SelectedRows.Count > 0)
    
        dataGridView1.Rows.RemoveAt(this.dataGridView1.SelectedRows[0].Index);
                    

此外,这只会删除一行。我希望用户可以选择多行。

【问题讨论】:

【参考方案1】:

此代码删除dataGridView1的选定项:

 private void btnDelete_Click(object sender, EventArgs e)
 
     foreach (DataGridViewRow item in this.dataGridView1.SelectedRows)
     
         dataGridView1.Rows.RemoveAt(item.Index);
     
 

【讨论】:

一般来说,修改与我们正在迭代的对象相关的对象并不总是安全的,索引也可能不会更新。 最佳实践是使用 for 循环而不是 foreach 循环并从末尾向后迭代。这有助于您保留索引并避免在迭代期间进行编辑时出现问题。 @Grungondola 你应该为此单独回答【参考方案2】:

这是一个非常简单的例子:

ASPX:

<asp:GridView ID="gvTest" runat="server" SelectedRowStyle-BackColor="#996633" 
       SelectedRowStyle-ForeColor="Fuchsia">
    <Columns>
        <asp:CommandField ShowSelectButton="True" />
        <asp:TemplateField>
            <ItemTemplate>
                <%# Container.DataItemIndex + 1 %>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
<asp:Button ID="btnUpdate" runat="server" Text="Update" OnClick="btnUpdateClick"/>

代码背后:

public partial class _Default : System.Web.UI.Page

    private readonly DataTable _dataTable;

    public _Default()
    
        _dataTable = new DataTable();

        _dataTable.Columns.Add("Serial", typeof (int));
        _dataTable.Columns.Add("Data", typeof (string));

        for (var i = 0; ++i <= 15;) 
        _dataTable.Rows.Add(new object[] i, "This is row " + i);
    

    protected void Page_Load(object sender, EventArgs e)
    
        if (!IsPostBack)
            BindData();
    

    private void BindData()
    
        gvTest.DataSource = _dataTable;
        gvTest.DataBind();
    

    protected void btnUpdateClick(object sender, EventArgs e)
    
        if (gvTest.SelectedIndex < 0) return;

        var r = gvTest.SelectedRow;

        var i = r.DataItemIndex;

        //you can get primary key or anyother column vlaue by 
        //accessing r.Cells collection, but for this simple case
        //we will use index of selected row in database.
        _dataTable.Rows.RemoveAt(i);

        //rebind with data
        BindData();

        //clear selection from grid
        gvTest.SelectedIndex = -1;
    

您必须使用复选框或其他一些机制来允许用户选择多行,然后您可以浏览选中复选框的行,然后删除这些行。

【讨论】:

【参考方案3】:

我写了如下代码,请看一下:

foreach (DataGridViewRow row in dataGridView1.SelectedRows)
    if (!row.IsNewRow) dataGridView1.Rows.Remove(row);

使用所选行的Index 仍然可以工作;看看下面的代码是否可以解决问题:

int selectedCount = dataGridView1.SelectedRows.Count;           
while (selectedCount > 0)

    if (!dataGridView1.SelectedRows[0].IsNewRow)
        dataGridView1.Rows.RemoveAt(dataGridView1.SelectedRows[0].Index);
    selectedCount--;

我希望这会有所帮助,问候。

【讨论】:

谢谢...我现在遇到的主要问题是使用 tableadapter 保存到数据库中。 您需要提供更多关于哪些内容不适合您的详细信息;我敢打赌,通过使用导致麻烦的代码片段开始一个新问题,你会得到最好的回应【参考方案4】:
private void btnDelete_Click(object sender, EventArgs e)

    if (e.ColumIndex == 10)// 10th column the button
    
        dataGridView1.Rows.Remove(dataGridView1.Rows[e.RowIndex]);
                    

此解决方案可以通过“e”参数删除一行(未选中,点击行!)。

【讨论】:

为什么不使用 foreach 呢?参考@Navid Farhadi 的回答。【参考方案5】:
private void buttonRemove_Click(object sender, EventArgs e)

    foreach (DataGridViewCell oneCell in dataGridView1.SelectedCells)
    
        if (oneCell.Selected)
            dataGridView1.Rows.RemoveAt(oneCell.RowIndex);
    

删除索引在选定单元格中的行。因此,选择任何单元格,它们对应的行将被删除。

【讨论】:

【参考方案6】:

要删除datagrid中的多行,c#

我的部分代码:

private void btnDelete_Click(object sender, EventArgs e)
    
        foreach (DataGridViewRow row in datagrid1.SelectedRows)
        
            //get key
            int rowId = Convert.ToInt32(row.Cells[0].Value);

            //avoid updating the last empty row in datagrid
            if (rowId > 0)
            
                //delete 
                aController.Delete(rowId);

                //refresh datagrid
                datagrid1.Rows.RemoveAt(row.Index); 
              
        
    




 public void Delete(int rowId)
        
            var toBeDeleted = db.table1.First(c => c.Id == rowId);
            db.table1.DeleteObject(toBeDeleted);
            db.SaveChanges();

        

【讨论】:

【参考方案7】:

这样看:

if (MessageBox.Show("Sure you wanna delete?", "Warning", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)

  foreach (DataGridViewRow item in this.dataGridView1.SelectedRows)
  
      bindingSource1.RemoveAt(item.Index);
  
      adapter.Update(ds);
 

【讨论】:

【参考方案8】:

试试这个:

if (dgv.SelectedRows.Count>0)

    dgv.Rows.RemoveAt(dgv.CurrentRow.Index);

【讨论】:

【参考方案9】:

好吧,这就是我通常如何从DataGridView 中删除用户检查的行的方式,如果您将其与来自Dataset 的 DataTable 相关联(例如:DataGridView1.DataSource = Dataset1.Tables["x"]),那么一旦您进行任何更新(删除、插入、更新)在Dataset 中,它会自动发生在你的DataGridView 中。

if (MessageBox.Show("Are you sure you want to delete this record(s)", "confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == System.Windows.Forms.DialogResult.Yes)
        
            try
            
                for (int i = dgv_Championnat.RowCount -1; i > -1; i--)
                
                    if (Convert.ToBoolean(dgv_Championnat.Rows[i].Cells[0].Value) == true)
                    
                        Program.set.Tables["Champ"].Rows[i].Delete();
                    
                
                Program.command = new SqlCommandBuilder(Program.AdapterChampionnat);
                if (Program.AdapterChampionnat.Update(Program.TableChampionnat) > 0)
                
                    MessageBox.Show("Well Deleted");
                
            
            catch (SqlException ex)
            
                MessageBox.Show(ex.Message);
            
        

【讨论】:

【参考方案10】:
private: System::Void button9_Click(System::Object^  sender, System::EventArgs^  e)

    String^ constring = L"datasource=localhost;port=3306;username=root;password=password";
    mysqlConnection^ conDataBase = gcnew MySqlConnection(constring);
    conDataBase->Open();
    try 
    
        if (MessageBox::Show("Sure you wanna delete?", "Warning", MessageBoxButtons::YesNo) == System::Windows::Forms::DialogResult::Yes)
        
            for each(DataGridViewCell^ oneCell in dataGridView1->SelectedCells)
            
                if (oneCell->Selected) 
                    dataGridView1->Rows->RemoveAt(oneCell->RowIndex);
                    MySqlCommand^ cmdDataBase1 = gcnew MySqlCommand("Delete from Dinslaken_DB.Configuration where Memory='ORG 6400H'");
                    cmdDataBase1->ExecuteNonQuery();
                    //sda->Update(dbdataset);
                   
                       
        
    
    catch (Exception^ex)
    
        MessageBox::Show(ex->ToString());
    

【讨论】:

【参考方案11】:
if(this.dgvpurchase.Rows.Count>1)

    if(this.dgvpurchase.CurrentRow.Index<this.dgvpurchase.Rows.Count)
    
        this.txtname.Text = this.dgvpurchase.CurrentRow.Cells[1].Value.ToString();
        this.txttype.Text = this.dgvpurchase.CurrentRow.Cells[2].Value.ToString();
        this.cbxcode.Text = this.dgvpurchase.CurrentRow.Cells[3].Value.ToString();
        this.cbxcompany.Text = this.dgvpurchase.CurrentRow.Cells[4].Value.ToString();
        this.dtppurchase.Value = Convert.ToDateTime(this.dgvpurchase.CurrentRow.Cells[5].Value);
        this.txtprice.Text = this.dgvpurchase.CurrentRow.Cells[6].Value.ToString();
        this.txtqty.Text = this.dgvpurchase.CurrentRow.Cells[7].Value.ToString();
        this.txttotal.Text = this.dgvpurchase.CurrentRow.Cells[8].Value.ToString();
        this.dgvpurchase.Rows.RemoveAt(this.dgvpurchase.CurrentRow.Index);
        refreshid();
    

【讨论】:

你能解释一下你的答案吗,光看代码是不够的【参考方案12】:
for (int j = dataGridView1.Rows.Count; j > 0 ; j--)

    if (dataGridView1.Rows[j-1].Selected)
        dataGridView1.Rows.RemoveAt(j-1);

【讨论】:

【参考方案13】:

首先从数据库中删除,然后然后更新您的datagridview

//let's suppose delete(id) is a method which will delete a row from the database and
// returns true when it is done
int id = 0;
//we suppose that the first column in the datagridview is the ID of the ROW :
foreach (DataGridViewRow row in this.dataGridView1.SelectedRows)
   id = Convert.ToInt32(row.Cells[0].Value.ToString());
if(delete(id))                               
   this.dataGridView1.Rows.RemoveAt(this.dataGridView1.SelectedRows[0].Index);
//else show message error!

【讨论】:

【参考方案14】:
private void btnDelete_Click(object sender, EventArgs e)

    dataGridView1.Rows.RemoveAt(dataGridView1.SelectedRows[0].Index);
                ?BindingSource.EndEdit();
                ?TableAdapter.Update(this.?DataSet.yourTableName);


//NOTE:
//? - is your data from database

例外不需要...或用您自己的代码更改。

代码:

数据库:

例如:prntscr.com/p3208c

数据库集:http://prntscr.com/p321pw

【讨论】:

只需编写代码,它就可以完成工作。示例:prntscr.com/p3208c【参考方案15】:

也许您可以使用临时列表进行删除。用于忽略行索引更改

<pre>
private void btnDelete_Click(object sender, EventArgs e)

    List<int> wantdel = new List<int>();
    foreach (DataGridViewRow row in dataGridView1.Rows)
    
        if ((bool)row.Cells["Select"].Value == true)
        wantdel.Add(row.Index);
    

    wantdel.OrderByDescending(y => y).ToList().ForEach(x =>
    
        dataGridView1.Rows.RemoveAt(x);
    );           

</pre>

【讨论】:

【参考方案16】:
   ArrayList bkgrefs = new ArrayList();
                    foreach (GridViewRow rowd in grdOptionExtraDetails.Rows)
                    
                        CheckBox cbf = (CheckBox)rowd.Cells[1].FindControl("chkbulk");

                            if (cbf.Checked)
                            
                                rowd.Visible = true;
                                 bkgrefs.Add(Convert.ToString(grdOptionExtraDetails.Data.Rows[rowd.RowIndex]["OptionID"]));

                            
                            else
                            
                                grdOptionExtraDetails.Data.Rows.RemoveAt(rowd.DataItemIndex);
                                rowd.Visible = false;
                            


                    

【讨论】:

欢迎来到 SO - 添加一些关于您发布的代码正在做什么以帮助 OP 理解它的评论可能很有用。【参考方案17】:

试试这个:

foreach (DataGridViewRow item in this.YourGridViewName.SelectedRows)

    string ConnectionString = (@"Data Source=DESKTOPQJ1JHRG\SQLEXPRESS;Initial Catalog=smart_movers;Integrated Security=True");

    SqlConnection conn = new SqlConnection(ConnectionString);
    conn.Open();
    SqlCommand cmd = new SqlCommand("DELETE FROM TableName WHERE ColumnName =@Index", conn);
    cmd.Parameters.AddWithValue("@Index", item.Index);
    int i = cmd.ExecuteNonQuery();

    if (i != 0)
    
        YourGridViewName.Rows.RemoveAt(item.Index);
        MessageBox.Show("Deleted Succefull!", "Great", MessageBoxButtons.OK, MessageBoxIcon.Information);
    
    else 
        MessageBox.Show("Deleted Failed!", "Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
    

【讨论】:

【参考方案18】:

它对我有用!

private: System::Void MyButton_Delete_Click(System::Object^ sender, System::EventArgs^ e) 
    // Удалить столбец(Row).
    MydataGridView->Rows->RemoveAt(MydataGridView->CurrentCell->RowIndex);

【讨论】:

【参考方案19】:

这对我有用:

private void btnRemove_Click(object sender, EventArgs e) 
    int count = dgvSchedule.SelectedRows.Count;

    while (count != 0) 
        dgvSchedule.Rows.RemoveAt(dgvSchedule.SelectedRows[0].Index);
        count--;
    
 

【讨论】:

以上是关于如何删除选定的 DataGridViewRow 并更新已连接的数据库表?的主要内容,如果未能解决你的问题,请参考以下文章

禁用按下CTRL时选择的DataGridView行

如何从select2多选中的选项列表中删除选定的选项并按选择的顺序显示选定的选项

如何从 DOM 中删除数组的选定索引并反映 React 状态的变化?

如何在选定点之前删除 git 历史记录

如何在 vi 编辑器中删除选定的文本

Python - 如何删除选定ListBox项目周围的边框?