4thSpace
4thSpace

Reputation: 44352

How to delete multiple rows in DataGridView?

I have a DataGridView on a winform. Below is a working sample that repros the problem. The grid has two columns - checkbox and textbox. I'm creating two rows of data.

I loop through and get any checked row. Then I try to delete them. In the loop where I'm removing rows, all goes well on the first iteration. r.Index is 0.

Coming into the second iteration is where things breakdown. r.Index is now -1 and r.Cells[1].Value is null.

Why is this happening and what is the right way to remove these rows?

public Form1() 
{
List<data> dataList = new List<data>();
dataList.Add(new data() {IsChecked=true, dept="dept1"});
dataList.Add(new data() {IsChecked=true, dept="dept2"});
BindingListView<data> view = new BindingListView<data>(dataList);
dataGridView1.DataSource = view;

var rows = SelectedRows();
foreach (DataGridViewRow r in rows) {
  var name = r.Cells[1].Value.ToString();
  dataGridView1.Rows.Remove(r);
}

List<DataGridViewRow> SelectedRows() {
  List<DataGridViewRow> rows = new List<DataGridViewRow>();
  foreach (DataGridViewRow row in dataGridView1.Rows) {
    if (Convert.ToBoolean(row.Cells[0].Value)) {
      rows.Add(row);
    }
   }
   return rows;
}

}


public class data 
{
  public bool IsChecked {get;set;}
  public string dept {get;set;}
}

BindingListView class comes from here: http://blw.sourceforge.net

Upvotes: 1

Views: 1549

Answers (1)

Reza Aghaei
Reza Aghaei

Reputation: 125312

You can remove checked item from the BindingListView<Data>. The changes will be shown in DataGridView immediately.

foreach (var item in view.ToList())
{
    if (item.IsChecked)
        view.Remove(item);
}

Using ToList() creates a different List<Data> which is used in the loop, so removing the item from original list is allowed and doesn't change the list we used in the loop.

Also as another option, you can remove the row from DataGridView this way. The changes will be made in the BindingListView<Data> immediately:

dataGridView1.Rows.Cast<DataGridViewRow>()
    .Where(row => (bool?)row.Cells[0].Value == true)
    .ToList().ForEach(row =>
    {
        dataGridView1.Rows.Remove(row);
    });

Upvotes: 1

Related Questions