C# WinForms DataGridView цвет фона рендеринга слишком медленно

Я рисую свои строки в DataGridView следующим образом:

private void AdjustColors()
    {            
        foreach (DataGridViewRow row in aufgabenDataGridView.Rows)
        {
            AufgabeStatus status = (AufgabeStatus)Enum.Parse(typeof(AufgabeStatus), (string)row.Cells["StatusColumn"].Value);

            switch (status)
            {
                case (AufgabeStatus.NotStarted):
                    row.DefaultCellStyle.BackColor = Color.LightCyan;
                    break;
                case (AufgabeStatus.InProgress):
                    row.DefaultCellStyle.BackColor = Color.LemonChiffon;
                    break;
                case (AufgabeStatus.Completed):
                    row.DefaultCellStyle.BackColor = Color.PaleGreen;
                    break;
                case (AufgabeStatus.Deferred):
                    row.DefaultCellStyle.BackColor = Color.LightPink;
                    break;
                default:
                    row.DefaultCellStyle.BackColor = Color.White;
                    break;
            }
        }        
    }

затем я вызываю его в методе OnLoad:

protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            AdjustColors();           
        } 

Я предпочитаю OnLoad OnPaint или что-то еще.. потому что OnPaint вызывается очень часто.

вопрос: почему требуется около 100 - 200 мс, чтобы изменить фон каждой строки? Раньше я не был CellPaint.. но у меня были проблемы при прокрутке с обновлением..

5 ответов


вместо изменения цвета целого DataGrid сразу, вы должны позволить ему управлять рендерингом, переопределяя CellFormatting событие. Строки будут окрашены только тогда, когда они фактически отображаются на экране.

private void aufgabenDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
  DataGridViewRow row = aufgabenDataGridView.Rows[e.RowIndex];
  AufgabeStatus status = (AufgabeStatus) Enum.Parse(typeof(AufgabeStatus), (string) row.Cells["StatusColumn"].Value);

  switch (status)
  {
    case (AufgabeStatus.NotStarted):
      e.CellStyle.BackColor = Color.LightCyan;
      break;
    case (AufgabeStatus.InProgress):
      e.CellStyle.BackColor = Color.LemonChiffon;
      break;
    case (AufgabeStatus.Completed):
      e.CellStyle.BackColor = Color.PaleGreen;
      break;
    case (AufgabeStatus.Deferred):
      e.CellStyle.BackColor = Color.LightPink;
      break;
    default:
      e.CellStyle.BackColor = Color.White;
      break;
  }

}

если это все еще слишком медленно, попробуйте получить реальный объект, к которому привязана строка:

...
DataGridViewRow row = aufgabenDataGridView.Rows[e.RowIndex];
var aufgabe = (Aufgabe) row.DataBoundItem;
AufgabeStatus status = aufgabe.Status;
...

вероятно, это перечисление.Разбор вызова, он имеет низкую производительность. Вы должны попытаться изменить его на поиск словаря, чтобы увидеть, улучшает ли это производительность. Смотрите это в должности


Как сказал SwDevMan1, вы должны сначала работать над удалением перечисления.Разбор вызова. Вы используете привязку данных для заполнения таблицы? Если это так, вы можете использовать Rows[index].DataBoundItem для доступа к объекту привязки данных для строки и прямого доступа к статусу AufgabeStatus.

вторая настройка, которую я бы предложил, - это вызов SuspendLayout () и ResumeLayout () до и ПОСЛЕ, соответственно, манипулирования сеткой.


также неплохо установить свойства, только если они отличаются от ожидаемого значения. Таким образом, вы не запускаете нежелательные внутренние накладные расходы DataGridView.

Если все ячейки в строке отформатированы одинаково, вы можете сделать форматирование на уровне строки вместо уровня ячейки.

DataGridViewCellStyle rowStyle = row.DefaultCellStyle;
if (rowStyle.BackColor != status.BackColor) { 
   rowStyle.BackColor = status.BackColor;
}

Не пытайтесь форматировать строки как ряд.defaultcellstyle

попробуйте форматирование отдельных ячеек в ufgabenDataGridView_CellFormatting

ячейки[0].стиль.цвет фона=цвет.желтый