Tip How to dramatically improve performance and stability of DataGridView

Rob Sherratt

Well-known member
Joined
Dec 30, 2012
Messages
64
Location
Corfu. Greece
Programming Experience
10+
Hopefully others may find this Tip useful, let me know if so?

I was developing a large Windows Forms application under .NET 4.5. The application uses two DataGridViews bound to DataTables in order to compare and edit data "before" and "after". The performance was lousy, taking up to 30 minutes to populate each DataGridView when the DataTables were being updated. Then my application would "crash" or completely "freeze out" requiring Task Manager intervention to close it. Eventually after several days tearing my remaining hair out, this is the solution:

When you drag and drop a DataGridView object to your Windows Form, the following property in Forms Designer is set as default:
Focus -> Causes Validation = True​

The resulting behaviour is that whenever a single cell of your DataTable changes, the entire DataGridView display is redrawn. When performing tens of thousands of data updates, this drastically slows down the Windows Form application (factor of several thousand!) to the extent of causing a complete application hang.

What I recommend is that people should in general set this property (in Forms Designer) to False. Then in your code, when you decide to redraw the DataGridView, just call:

VB.NET:
MyDataGridView.Refresh()

This also has the unwanted side-effect of losing the current user cell selection, so I set the Behaviour -> MultiSelect property to "False" to ensure only one cell at a time can be selected by the user. Then my code to handle the refresh/ deselected cell problem is as follows:

VB.NET:
MySelRow = MyDataGridView.SelectedCells(0).RowIndex         ' only one value is permitted due to MultiSelect = False
MySelCol = MyDataGridView.SelectedCells(0).ColumnIndex       ' only one value is permitted due to MultiSelect = False
MyDataGridView.Refresh()
MyDataGridView.Rows(MySelRow).Cells(MySelCol).Selected = True

Now, if your application permits multiple selected cells then you will have to iterate through all SelectedCells(n).RowIndex and save them in a MySelRow(n) array, similarly for SelectedCells(n).ColumnIndex into a MySelCol(n) array. Then modify the .Selected = True code to enclose it in a double For Next statement. I have not tested this myself since my application is a bit simpler in only permitting a single cell at a time to ever be selected.

Hope this is helpful to others,
Best regards,
Rob
 
Last edited:
Back
Top