简体   繁体   中英

Delete Multiple rows from datagridview

I've a datagridview in which values are inserted.The gridview is like this.

    Item                PRID                 
   ------              ------               
    Item1                1
    Item2                2
    Item3                2

I am trying to compare the PRID with a variable which holds the selected row PRID. What I've done so far.

                foreach (DataGridViewRow dgv_r in PurchaseOrder_dgv.Rows)
                {
                    if (dgv_r.Cells[1].Value.ToString() == CurrentSelected_PRID_ForPurchaseOrder.ToString())
                    {
                        PurchaseOrder_dgv.Rows.Remove(dgv_r);
                    }
                }

But it deletes the bottom row not the second row.and gives the following error.What I want is if the value of CurrentSelected_PRID_ForPurchaseOrder is equal to 2 then it should delete both the rows.I've tried it using for loop also but it gives me Index out of range error.It is giving the following error.

 Object Reference Not set to an instance of object

The are a couple of ways around this. One is to do the following

for (int i = dataGridView1.RowCount - 1; i >= 0; i--)
    if (String.Compare(dataGridView1.Rows[i].Cells[1].Value.ToString(), "2") == 0)
        dataGridView1.Rows.Remove(dataGridView1.Rows[i]);

This is looping from the bottom end of the DataGridView and avoids the problem with removing rows whilst iterating.

I hope this helps.

As mellamokb pointed out the reason is because your editing the collection during the foreach. One solution would be to store the rows with the same PRID in a list first and then remove them after. Something like this

var rowsToRemove = new List<int>();

foreach (DataGridViewRow dgv_r in PurchaseOrder_dgv.Rows)
{
    if (dgv_r.Cells[1].Value.ToString() == CurrentSelected_PRID_ForPurchaseOrder.ToString())
    {
        rowsToRemove.Add(dgv_r.Index);
    }
}

rowsToRemove.Reverse();
rowsToRemove.ForEach(i => PurchaseOrder_dgv.Rows.RemoveAt(i));

Another solution is to use a while loop instead which takes into account the possiblity of the collection size changing.

int i = 0;
while (i < PurchaseOrder_dgv.Rows.Count)
{
    if (PurchaseOrder_dgv.Rows[i].Cells[1].Value.ToString() == CurrentSelected_PRID_ForPurchaseOrder.ToString())
    {
        PurchaseOrder_dgv.Rows.RemoveAt(i);
    }
    i++;
}

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