Hiding a row in a DataGridView is very slow

I have a DataGridView in a Winforms application that has about 1000 rows (unbound) and 50 columns. Hiding a column takes 2 seconds. When I want to hide about half of the lines, this becomes a problem.

private void ShowRows(string match) { this.SuspendLayout(); foreach (DataGridViewRow row in uxMainList.Rows) { if (match == row.Cells["thisColumn"].Value.ToString())) { row.Visible = false; } else { row.Visible = true; } } this.ResumeLayout(); } 

I did some testing by adding Console.WriteLine(DateTime.Now) around actions, and row.Visible = false is definitely a slow bit. Am I missing something obvious, like setting IsReallySlow = false ? Or do I need to go ahead and activate virtual mode and encode the necessary events?

+4
source share
5 answers

It seems to me that you should use row filters.

Try using a DataView as a binding source and use DataView.RowFilter to hide rows or display rows of your choice.

 DataGridView myGridView = new DataGridView(); DataView myDataView = myTable.DefaultView; myGridView.DataSource = myDataView; // DataView that allows row filtering myDataView.RowFilter = string.Format("thisColumn <> '{0}'",match); // this will hide all rows where "thisColumn" = match 
+10
source

In most cases, the DataGridViewAutoSizeColumnMode property makes a slow DGV. Your performance increases dramatically when you change all columns to DataGridViewAutoSizeColumnMode.None mode. Subsequently, you can reset in the same way as in the previous state.

 For Each col As DataGridViewColumn In myDGV.Columns col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None Next 

You will see that hiding some of the 1000 columns now only takes 1-2 seconds. With other properties (SuspendLayout, Hiding the whole form, etc.) I could not find any effect.

+4
source

As mentioned above, its DataGridViewAutoSizeColumnMode , which kills performance. Instead of DatagridView over all the rows of the DatagridView and changing the autosave mode, do it instead of everything for the DatagridView , first DatagridView it off and then on again after the required row logic

 YourDatagridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None // Perform row visibility here... YourDatagridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells 
+2
source

Just a question. Is it possible to pass this matching parameter to the query or database procedure and get rows that do not match the records. This way you just don’t have to worry about showing / hiding, and it will be faster since you will no longer be looped. This will also work with increasing the number of records over time.

Just a thought that may not apply to you ... let me know.

0
source

To implement optimization to speed up row selection in a DataGridViewRow based on the reset property of AutoSizeColumnsMode , you can use this class:

 Public Class DataGridViewUtil Private dgv As DataGridView Private sizeColumnModeBackup(-1) As DataGridViewAutoSizeColumnMode Public Sub New(dgv As DataGridView) Me.dgv = dgv End Sub ''' <summary> ''' Prepare datagridview before we do the row hidding to speedup it ''' </summary> ''' <remarks>We use a method based on reseting the AutoSizeColumnMode ''' property to None, therefore it will be necessary to call ''' HidingRowsSpeederAfer() when we finish hiding rows</remarks> Public Sub HidingRowsSpeederBefore() ReDim sizeColumnModeBackup(dgv.Columns.Count) For Each col As DataGridViewColumn In dgv.Columns sizeColumnModeBackup(col.Index) = col.AutoSizeMode col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None Next End Sub ''' <summary> ''' Restore DataGridView state changed when HidingRowsSpeederBefore() ''' was called ''' </summary> ''' <remarks>This procedure must be called after the row hidding has been ''' done and requires a previous call to HidingRowsSpeederBefore()</remarks> Public Sub HidingRowsSpeederAfter() If dgv Is Nothing Then Throw New NullReferenceException("The assigned datagridview is null") End If If sizeColumnModeBackup.Length < dgv.Columns.Count Then Throw New Exception("Mismatch on internal SizeColumnMode array, " & "maybe you forgot to call HidingRowsSpeederBefore()") End If For Each col As DataGridViewColumn In dgv.Columns col.AutoSizeMode = sizeColumnModeBackup(col.Index) Next End Sub End Class 

How to use it:

  Dim dgvUtil As New DataGridViewUtil(yourDataGridView) dgvUtil.HidingRowsSpeederBefore() '... do your row hidding chores here dgvUtil.HidingRowsSpeederAfter() 
0
source

Source: https://habr.com/ru/post/1304647/


All Articles