Reputation: 44352
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
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