I'm working on an app for my company, and the users have the ability to load a lot of rows into a DataGridView. That hasn't been a problem, but when the user selects more than ~20 rows to delete, the app hangs and becomes unresponsive. While there are methods to just take the specific form out and put the operation on a background worker thread, I couldn't imagine what the problem could possibly be. What I was doing is getting an array of rows from the DataTable.Select() method, and then I would loop through the results and do the Remove() method of the DataTable. I had a key on this DataTable, so I tried dropping that, but it wasn't working. I did a few Google searches, but couldn't find the answer. I'm usually pretty good at searching Google, but this time, it was a desert out there.
The SolutionIt occured to me that the DataTable.Clear() method is pretty fast, and adding rows is pretty quick, so the solution is to create a new DataTable, add the rows to keep in that DataTable, clear out the original table, and then call Merge() on it to bring in the kept rows.
DataTable myDataTable; //this would actually be a strongly typed DataSet in my case.
private void Example()
{
DataRow[] dataRows = myDataTable.Select("Selected=true");
//turn off the event for a bit
myDataTable.RowDeleted -= myDataTable_RowDeleted;
if (dataRows.Length == myDataTable.Rows.Count)
{
myDataTable.Clear();
}
else if (dataRows.Length > 20)
{
DataTable myNewDataTable = new DataTable();
dataRows = myDataTable.Select("Selected=false");
DataRow newRow;
foreach (DataRow row in dataRows)
{
newRow = myNewDataTable.NewRow();
newRow.Col1 = row.Col1;
newRow.Col2 = row.Col2;
myNewDataTable.Rows.Add(newRow);
}
myDataTable.Clear();
myDataTable.Merge(myNewDataTable);
}
else
{
//it's ok to loop through 20 or fewer
foreach (DataRow selectedRow in dataRows)
myDataTable.Rows.Remove(selectedRow);
}
//turn the event back on
myDataTable.RowDeleted += myDataTable_RowDeleted;
}
