2016-09-04 61 views
2

如何修復CellFormatting「慢速滾動」性能問題?DataGridView CellFormatting性能問題

我使用此代碼解密值從加密列複製到另一列:

private void grid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) 
{ 
    if (e.ColumnIndex < 0 || e.RowIndex < 0) 
     return; 

    var columnB = grid.Columns[e.ColumnIndex]; 
    if (columnB.Name != "B") 
     return; 

    var value = grid.Rows[e.RowIndex].Cells["A"].Value; 
    if (value == null || value == DBNull.Value) 
     return; 

    e.Value = Decrypt(value.ToString()); 
} 
+0

如果問題實際上是CellPainting,則可以使用DoubleBuffered DGV。如果解密是,那麼你可以把解密的值放在Cell.Tag中,但這可能不是你想要的安全方式.. – TaW

+0

@TaW它的doublebuffered dgv。 – X11

+0

可以肯定的是:您使用DoubleBuffered DataGridView __subclass__? (許多新手相信他們可以通過Form的DoubleBuffered屬性爲所有控件啓用DoubleBuffering ..) – TaW

回答

2

如果性能問題是因爲Decrypt方法,你應該在的言論部分提到避免使用它在CellFormatting事件的單證:

CellFormatting事件發生於每個單元是畫的時間,所以 處理該事件時,你應該避免冗長的處理。

我可以使用什麼解決方案爲第二列提供基於第一列的值?

您可以使用這些選項:

  1. 添加第二列DataGridView並在for循環中提供的價值。
  2. 將第二列添加到您的數據源(例如您的DataTable)並在for循環中提供值。

在下面的示例,如果從數據庫加載數據不作任何區別。但是,爲了提供一個最小的完整可驗證的例子,我自己創建了DataTable。在這兩個例子LoadData方法,加載DataTable

private DataTable LoadData() 
{ 
    var dt = new DataTable(); 
    dt.Columns.Add("ExistingColumn"); 
    dt.Rows.Add("x"); 
    dt.Rows.Add("y"); 
    dt.Rows.Add("z"); 
    return dt; 
} 

實施例1 - 添加列的DataGridView

var dt = LoadData(); 
dataGridView1.DataSource = dt; 
//Add new column to DataGridView 
var newColumn = new DataGridViewTextBoxColumn(); 
newColumn.HeaderText = "NewColumn"; 
newColumn.Name = "NewColumn"; 
dataGridView1.Columns.Add(newColumn); 
//Copy Values 
foreach (DataGridViewRow r in this.dataGridView1.Rows) 
{ 
    if(!r.IsNewRow) 
     r.Cells["NewColumn"].Value = Decrypt(r.Cells["ExistingColumn"].Value.ToString()); 
} 

實施例2 - 添加列到數據表

var dt = LoadData(); 
dataGridView1.DataSource = dt; 
//Add new column to DataTable 
dt.Columns.Add("NewColumn"); 
//Copy Values 
foreach (DataRow r in dt.Rows) 
    r["NewColumn"] = Decrypt(r.Field<string>("ExistingColumn"); 
+0

在示例中,我沒有對「ExistingColumn」的值執行null/dbnull檢查。您可能需要檢查列中是否存在空/ dbull值。 –

+0

您是否像我一樣在乾淨的環境中進行測試?讓我知道如果你有任何問題的答案:) –

+0

謝謝,Ex2對我很好。 – X11

0

不要使用CellFormating方法。

我終於找到了很好的工作解決方案。

這是我的代碼。

dgvTrucksMaster.SuspendLayout(); 
dgvTrucksMaster.DataSource = calendar.FailureCalendarDetails.OrderBy(x => x.MachineFullName).ToList(); 

foreach (DataGridViewRow row in dgvTrucksMaster.Rows) 
{ 
    if (Convert.ToDouble(row.Cells["Decade1Hours"].Value) > 0) 
    { 
     row.Cells["Decade1Hours"].Style.BackColor = Color.LightGreen; 
    } 

    if (Convert.ToDouble(row.Cells["Decade1Hours"].Value) < 0) 
    { 
     // row.DefaultCellStyle.BackColor = Color.LightSalmon; 
     row.Cells["Decade1Hours"].Style.BackColor = Color.LightSalmon; 
    } 

    if (Convert.ToDouble(row.Cells["Decade2Hours"].Value) > 0) 
    { 
     row.Cells["Decade2Hours"].Style.BackColor = Color.LightGreen; 
    } 

    if (Convert.ToDouble(row.Cells["Decade2Hours"].Value) < 0) 
    { 
     // row.DefaultCellStyle.BackColor = Color.LightSalmon; 
     row.Cells["Decade2Hours"].Style.BackColor = Color.LightSalmon; 
    } 

    if (Convert.ToDouble(row.Cells["Decade3Hours"].Value) > 0) 
    { 
     row.Cells["Decade3Hours"].Style.BackColor = Color.LightGreen; 
    } 

    if (Convert.ToDouble(row.Cells["Decade3Hours"].Value) < 0) 
    { 
     // row.DefaultCellStyle.BackColor = Color.LightSalmon; 
     row.Cells["Decade3Hours"].Style.BackColor = Color.LightSalmon; 
    } 

    if (Convert.ToDouble(row.Cells["DecadeMonthHours"].Value) > 0) 
    { 
     row.Cells["DecadeMonthHours"].Style.BackColor = Color.LightGreen; 
    } 

    if (Convert.ToDouble(row.Cells["DecadeMonthHours"].Value) < 0) 
    { 
     // row.DefaultCellStyle.BackColor = Color.LightSalmon; 
     row.Cells["DecadeMonthHours"].Style.BackColor = Color.LightSalmon; 
    } 

    for (int i = 0; i < 61; i++) 
    { 
     if (Convert.ToDouble(row.Cells[string.Format("D{0}", i + 1)].Value) < 0) 
     { 
      row.Cells[string.Format("D{0}", i + 1)].Style.BackColor = Color.LightSalmon; 
     } 


     if (Convert.ToDouble(row.Cells[string.Format("D{0}", i + 1)].Value) > 0) 
     { 
      row.Cells[string.Format("D{0}", i + 1)].Style.BackColor = Color.LightGreen; 
     } 
    } 
} 

dgvTrucksMaster.ResumeLayout(); 

正如你從代碼中看到的,關鍵是要改變CellFormating應用Data Source之前ResumeLayout方法之後。

試試吧,你會滿意的結果。

哦!並確保你在BeginInvoke((Action)(() => { // Some code });代碼內完成。所以請儘早準備Data Source