Сокрытие строки в DataGridView очень медленно - PullRequest
4 голосов
/ 20 марта 2010

У меня есть DataGridView в приложении Winforms, которое имеет около 1000 строк (несвязанных) и 50 столбцов. Скрытие столбца занимает целых 2 секунды. Когда я хочу скрыть около половины строк, это становится проблемой.

    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? Или я должен пойти дальше и включить виртуальный режим и кодировать необходимые события?

Ответы [ 5 ]

10 голосов
/ 21 марта 2010

Мне кажется, вы должны использовать вместо этого фильтры строк.

Попробуйте использовать 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
4 голосов
/ 22 октября 2013

В большинстве случаев свойство DataGridViewAutoSizeColumnMode замедляет DGV. Ваша производительность резко возрастает, когда вы меняете все столбцы на Mode DataGridViewAutoSizeColumnMode.None. После этого вы можете сбросить его таким же образом в предыдущее состояние.

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

Вы увидите, что скрытие некоторых из 1000 столбцов теперь занимает всего 1-2 секунды. С другими свойствами (SuspendLayout, Скрытие всей формы и т. Д.) Я не смог найти никакого эффекта.

2 голосов
/ 12 января 2016

Как упомянуто выше, это DataGridViewAutoSizeColumnMode, который убивает производительность. Вместо того, чтобы циклически проходить по каждой строке DatagridView и изменять режим автоматического изменения размера, делайте это вместо всего Datagridview, сначала отключив его, а затем включив снова после выполнения требуемой логики строк

YourDatagridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None

     // Perform row visibility here...

YourDatagridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells
0 голосов
/ 12 апреля 2016

Чтобы реализовать оптимизацию для ускорения скрытия строк в DataGridViewRow на основе сброса свойства AutoSizeColumnsMode, вы можете использовать этот класс:

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()
0 голосов
/ 21 марта 2010

Просто вопрос. Можно ли передать этот параметр соответствия в запрос или процедуру базы данных и получить строки, которые не соответствуют записям. Таким образом, вам не нужно беспокоиться о показе / скрытии, и это будет быстрее, так как вы больше не будете зацикливаться Это также будет работать, так как количество записей увеличивается со временем.

Просто мысль, которая может быть неприменима для вас .. дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...