2012-01-03 489 views
2

我一直在用CellFormatting事件掙扎,它太慢了。C#中的CellFormatting事件真的很慢

我有一個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。現在我不知道我該如何處理這個C​​ellFormatting事件...

回答

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

[編輯1]

添加了代碼示例。

[編輯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

[編輯3](響應低於伊赫桑的評論)

這是因爲「a」是即時顯示在網格中的值,而原始行執行了一些重要工作: *執行搜索所需的值,包括所有子控件 *創建一個數組與發現結果 *使從對象強制轉換爲複選框 *它所有的這每每一條線在你的網格

因此很顯然,這變得更加耗時,你有更多的項目在您的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'臨時掛起控件的佈局邏輯.' – 2012-01-03 12:25:56

+0

感謝您的回覆,請您給出更詳細的答案,或者因爲我不知道如何使用此功能以及在哪裏? – Ehsan 2012-01-03 12:33:41

+0

其實我做了你所說的,但即使我看到更多的延遲,仍然有這種延遲!但我應該怎麼做?你認爲也許dataGridView1 [0,i]有一些錯誤,並使延遲?:( – Ehsan 2012-01-03 13:44:02