Why is removing rows in DataGridView so slow?

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I have a DataGridView with VirtualMode = true. The performance is great for
displaying many thousands of rows. However, if I remove a block of rows in
the middle of the grid, it takes multiple seconds while the scroll bar moves
around a lot, then the rows below finally get repainted. If I add the same
block of rows back in, performance is fine. The added rows appear almost
immediately.

The problem seems to be worse as I move farther down in the row set.

I tried 2 approaches to removing these rows. First, I simple decrement the
RowCount by the number of rows I want to remove. The 2nd approach was to do
this:

for (int n = nStart; n < nStart + count; n++)
grid.Rows.RemoveAt(n);

Same performance. In fact, when I use Reflector to see what RemoveAt() is
doing, it looks like it just decrements the RowCount.

Why should it be so slow? Is there anything I can do to speed this up?
 
In doing some more on line trolling, I found a solution on a blog post. The
answer is clear all the Rows, then set the RowCount to what I want. Here is
what I can do to remove a bunch of records from deleteStart to deleteStart +
count:

// Cache the first visible cell because when we clear the rows, we would
lose our scroll position
DataGridViewCell cell = grid.FirstDisplayedCell;
int firstVisibleColIndex = cell.ColumnIndex;
int firstVisibleRowIndex = cell.RowIndex;

// New RowCount after I remove the block of Rows
int rowCount = grid.RowCount - count;

grid.Rows.Clear();
grid.RowCount = rowCount;

cell = grid[firstVisibleColIndex, firstVisibleRowIndex];
grid.FirstDisplayedCell = cell;

Works great! And it happens essentially instantaneously. Note that the above
code is display only. I didn't show you the BL that describes how I remove
the rows from my underlying datastore, but that code executes in almost no
time anyway so that was not my issue.
 
I had this issue as well, but found an easier way to resolve it. Just switch to RemoveAt, its instant and much cleaner.

Old code:

foreach (DataGridViewRow dgvRow in dgvDevices.SelectedRows)
dgvDevices.Rows.Remove(dgvRow);

New code:

foreach (DataGridViewRow dgvRow in dgvDevices.SelectedRows)
dgvDevices.Rows.RemoveAt(dgvRow.Index);


The remove used to take forever, but now its instant.



PeteMos wrote:

In doing some more on line trolling, I found a solution on a blog post.
04-Aug-07

In doing some more on line trolling, I found a solution on a blog post. The
answer is clear all the Rows, then set the RowCount to what I want. Here is
what I can do to remove a bunch of records from deleteStart to deleteStart +
count

// Cache the first visible cell because when we clear the rows, we would
lose our scroll positio
DataGridViewCell cell = grid.FirstDisplayedCell
int firstVisibleColIndex = cell.ColumnIndex
int firstVisibleRowIndex = cell.RowIndex

// New RowCount after I remove the block of Row
int rowCount = grid.RowCount - count

grid.Rows.Clear()
grid.RowCount = rowCount

cell = grid[firstVisibleColIndex, firstVisibleRowIndex]
grid.FirstDisplayedCell = cell

Works great! And it happens essentially instantaneously. Note that the above
code is display only. I didn't show you the BL that describes how I remove
the rows from my underlying datastore, but that code executes in almost no
time anyway so that was not my issue.

Previous Posts In This Thread:

Why is removing rows in DataGridView so slow?
I have a DataGridView with VirtualMode = true. The performance is great for
displaying many thousands of rows. However, if I remove a block of rows in
the middle of the grid, it takes multiple seconds while the scroll bar moves
around a lot, then the rows below finally get repainted. If I add the same
block of rows back in, performance is fine. The added rows appear almost
immediately

The problem seems to be worse as I move farther down in the row set

I tried 2 approaches to removing these rows. First, I simple decrement the
RowCount by the number of rows I want to remove. The 2nd approach was to do
this

for (int n = nStart; n < nStart + count; n++
grid.Rows.RemoveAt(n)

Same performance. In fact, when I use Reflector to see what RemoveAt() is
doing, it looks like it just decrements the RowCount

Why should it be so slow? Is there anything I can do to speed this up?

In doing some more on line trolling, I found a solution on a blog post.
In doing some more on line trolling, I found a solution on a blog post. The
answer is clear all the Rows, then set the RowCount to what I want. Here is
what I can do to remove a bunch of records from deleteStart to deleteStart +
count

// Cache the first visible cell because when we clear the rows, we would
lose our scroll positio
DataGridViewCell cell = grid.FirstDisplayedCell
int firstVisibleColIndex = cell.ColumnIndex
int firstVisibleRowIndex = cell.RowIndex

// New RowCount after I remove the block of Row
int rowCount = grid.RowCount - count

grid.Rows.Clear()
grid.RowCount = rowCount

cell = grid[firstVisibleColIndex, firstVisibleRowIndex]
grid.FirstDisplayedCell = cell

Works great! And it happens essentially instantaneously. Note that the above
code is display only. I didn't show you the BL that describes how I remove
the rows from my underlying datastore, but that code executes in almost no
time anyway so that was not my issue.

EggHeadCafe - Software Developer Portal of Choice
Pass Classes in ASP.NET with LosFormatter
http://www.eggheadcafe.com/tutorial...03-4135280f8c3a/pass-classes-in-aspnet-w.aspx
 
Back
Top