2012-01-03 2 views
2

Я боролся с событием CellFormatting, это так медленно.Событие CellFormatting в C# очень медленное

У меня есть DataGridView что-то вроде этого:

enter image description here

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

private void checkboxHeader_CheckedChanged(object sender, EventArgs e) 
    { 
     for (int i = 0; i < dataGridView1.RowCount; i++) 
     { 
      dataGridView1[0, i].Value = ((CheckBox)dataGridView1.Controls.Find("checkboxHeader", true)[0]).Checked; 
     } 
     //dataGridView1.EndEdit(); 
    } 

И эта функция работает, когда у меня есть что-то вроде 10 строк он работает отлично, но когда у меня есть 300 строк то, что я должен иметь ... есть что-то вроде задержки 9 секунд для принятия всех флажки и я узнал, что это связано с событием CellFormating.

Мой CellFormating код события:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
     { 

      DataGridViewCellStyle _myStyle = new DataGridViewCellStyle(); 
      int index = gdv_row.FindIndex(p => p.log == (string)dataGridView1.Rows[e.RowIndex].Cells[1].Value); 
      if (index != -1 && dataGridView1.Columns[e.ColumnIndex] is DataGridViewTextBoxColumn && e.RowIndex != -1) 
      { 
       //e.CellStyle = _myStyle; 
       _myStyle.Font = gdv_row[index].font; 
       _myStyle.BackColor = gdv_row[index].backgroundcolor_color; 
       _myStyle.ForeColor = gdv_row[index].foregroundcolor_color; 
       dataGridView1.Rows[e.RowIndex].Cells[1].Style = _myStyle; 
      } 
     } 

и я использовал DoubleBuffering for DataGridView. Теперь я не знаю, что мне делать с этим событием CellFormatting ...

ответ

3

Вы уже пробовали SuspendLayout() и ResumeLayout()?

Это временно приостанавливает логику компоновки для управления, так что при ее заполнении нет перерисовывания сетки.

Если вы используете DoubleBuffering, сетка по-прежнему выводит на экран все, что еще медленнее. Но если вы не перерисовываете вообще, пока вы заполняете грид, это должно дать драматическое движение.

Ваша первая функция может выглядеть следующим образом:

private void checkboxHeader_CheckedChanged(object sender, EventArgs e) 
    { 
     dataGridView1.SuspendLayout(); 

     for (int i = 0; i < dataGridView1.RowCount; i++) 
     { 
      dataGridView1[0, i].Value = ((CheckBox)dataGridView1.Controls.Find("checkboxHeader", true)[0]).Checked; 
     } 

     dataGridView1.ResumeLayout(); 
    } 

[Edit 1]

Добавлен пример кода.

[Edit 2] Для минимизации необходимого рисунка строк, вместо того, чтобы создать новый объект DataGridViewCellStyle для каждой строки, попытайтесь установить свойство существующего стиля непосредственно:

private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
    { 
     int index = gdv_row.FindIndex(p => p.log == (string)dataGridView1.Rows[e.RowIndex].Cells[1].Value); 
     if (index != -1 && dataGridView1.Columns[e.ColumnIndex] is DataGridViewTextBoxColumn && e.RowIndex != -1) 
     { 
      dataGridView1.Rows[e.RowIndex].Cells[1].Style.Font = gdv_row[index].font; 
      dataGridView1.Rows[e.RowIndex].Cells[1].Style.BackColor = gdv_row[index].backgroundcolor_color; 
      dataGridView1.Rows[e.RowIndex].Cells[1].Style.ForeColor = gdv_row[index].foregroundcolor_color; 
     } 
    } 

Наконец, ищу какое-то решение, я нашел эту статью MSDN документ: Best Practices for Scaling the Windows Forms DataGridView Control

[EDIT 3] (Ответ на комментарий Ehsan в поле ниже)

Это потому, что «a» - это значение, которое мгновенно появляется для отображения в сетке, в то время как исходная строка выполняет некоторую значительную работу: * Выполняет поиск требуемого значения, включая все дочерние элементы управления. * Создает массив с найденными результатами * делает Cast от объекта CheckBox * Он делает все это за все и каждую строку в сетке

становится очевидным, что это становится больше времени, тем больше предметов вы имеете в вашем DataGridView ,

Если я понял ваш код правильно, это должно помочь вам изменить метод в этом:

CheckBox headerBox = ((CheckBox)dataGridView1.Controls.Find("checkboxHeader", true)[0]); 
    for (int i = 0; i < dataGridView1.RowCount; i++) 
    { 
    dataGridView1[0, i].Value = headerBox.Checked; 
    } 

Делая это, вы только выполнить поиск сразу.

+0

SuspendLayout собирается помочь вам, когда вы добавляете новый объектов на форме. Согласно MSDN, SuspendLayout 'Временно приостанавливает логику компоновки для элемента управления. ' –

+0

Спасибо за ответ, не могли бы вы дать ответ более подробно или как это, потому что я не знаю, как использовать эти функции и где? – Ehsan

+0

На самом деле я сделал то, что вы сказали, но есть еще эта задержка, даже я вижу большую задержку! но что мне делать? вы думаете, что у dataGridView1 [0, i] есть некоторая ошибка, и это задерживает? :( – Ehsan

0

Если вы хотите, чтобы остановить покраску контроль, когда вы проверяете все строки, вы должны смотреть на DrawingControl класса с этого поста: https://stackoverflow.com/questions/487661/...

Смежные вопросы