2009-10-27 81 views
8

我畫在這樣一個DataGridView我行太慢:C#的WinForms 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 ms來改變每一行的背景是什麼? 早期,我doint CellPaint ..但我刷新時滾動時遇到問題..

+0

你的意思是每行需要100 - 200ms?這聽起來很重。 – leppie

+0

多少行?你在表單上有雙緩衝設置嗎?你有沒有嘗試過使用CellFormatting事件? – stuartd

回答

10

您應該讓它通過覆蓋CellFormatting事件來管理渲染,而不是一次更改整個DataGrid的顏色。這些行只會在屏幕上實際顯示時才被繪製。

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

嗯,這個解決方案無縫工作。 –

+0

這可能是我不能畫處理自己的證明,但我靠的是MS提供的機制。 現在所有的行會立即重新着色! –

+0

我刪除了Enum。由ShDevMan提議的解析 –

2

它可能是Enum.Parse調用,它性能差。您應該嘗試將其更改爲字典查找以查看是否可以提高性能。看到這個post

+0

你說得對,Enum.Parse足夠慢。我寧可直接訪問DataBoundItem。 –

2

正如SwDevMan1說,你應該先上取下Enum.Parse調用工作。你使用數據綁定來填充網格嗎?如果是這樣,您可以使用Rows [index] .DataBoundItem來訪問該行的數據綁定對象,並直接訪問AufgabeStatus狀態。

第二TWEAK我建議分別是前和之後調用SuspendLayout()和ResumeLayout(),操縱所述網格。

+0

我刪除了Parse調用。是的,我正在使用DataBounding。我通過DataBoundItem直接訪問元素。我嘗試了暫停和恢復。它更快..但15行仍然在約400毫秒着色.. –

2

這也是一個好主意,只有當他們從預期值不同設置的屬性。這樣你就不會觸發不需要的內部DataGridView開銷。

如果行中的所有單元格的格式以同樣的方式,你可以做行級,而不是細胞水平的格式。

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

不要嘗試行的格式 作爲row.defaultcellstyle

嘗試單個細胞中 ufgabenDataGridView_CellFormatting

格式化

細胞[0] = .style.backcolor color.yellow