2010-03-20 71 views
4

我有一個WinForms應用程序中有大約1000行(未綁定)和50列的DataGridView。隱藏一列需要2秒。當我想隱藏大約一半的行時,這成爲一個問題。在DataGridView中隱藏行很慢

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(); 
    } 

我做了一些測試,通過將圍繞行動Console.WriteLine(DateTime.Now)添加和row.Visible = false絕對是慢一點。我是否缺少明顯的東西,比如設置IsReallySlow = false?或者我必須繼續並啓用虛擬模式並編寫必要的事件代碼?

回答

10

它看起來像我應該使用行過濾器來代替。

嘗試使用DataView作爲綁定源並使用DataView.RowFilter隱藏行或顯示所選行。

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 
+0

這就是我最終做的,它運作得很好。謝謝! – 2010-03-21 15:51:48

0

只是一個問題..是否有可能將該匹配參數傳遞給數據庫查詢或過程,並獲取不匹配記錄的行。這樣你就不必擔心顯示/隱藏,它會更快以及你將不再循環。這也會隨着記錄數量隨時間而增加。

只是一個想法,可能不適用於你..我知道。

4

在大多數情況下,DataGridViewAutoSizeColumnMode屬性使DGV變慢。 當您將所有列更改爲模式DataGridViewAutoSizeColumnMode.None時,性能會急劇增加。之後,您可以按照與之前狀態相同的方式重置它。

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

您將看到隱藏1000列中的一些現在只需要1-2秒。與其他屬性(SuspendLayout,隱藏整個表單等),我找不到任何效果。

+0

你是絕對正確的。很好的發現。 – 2017-11-03 19:58:31

2

如上所述,其DataGridViewAutoSizeColumnMode殺死表現。取而代之的,而不是通過DatagridView的每一行循環和改變自動調整大小模式,做它爲整個Datagridview,由最初關閉它,然後你已經完成後,再次打開它所需的排邏輯

YourDatagridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None 

    // Perform row visibility here... 

YourDatagridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells 
0

向實現優化,加快行hidding的基礎上,AutoSizeColumnsMode屬性復位的DataGridViewRow你可以使用這個類:

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 

如何使用它:

Dim dgvUtil As New DataGridViewUtil(yourDataGridView) 
    dgvUtil.HidingRowsSpeederBefore() 

    '... do your row hidding chores here 

    dgvUtil.HidingRowsSpeederAfter()