DataGridView CellFormatting性能问题

时间:2016-09-04 19:55:08

标签: c# winforms 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());
}

2 个答案:

答案 0 :(得分:3)

如果性能问题是由Decrypt方法引起的,则应避免在CellFormatting中使用它,如事件文档的备注部分所述:

  

每次绘制每个单元格时都会发生CellFormatting事件,所以   处理此事件时应避免冗长处理。

我可以使用哪种解决方案根据第一列为第二列提供价值?

您可以使用以下任一选项:

  1. 将第二列添加到DataGridView并在for循环中提供值。
  2. 将第二列添加到数据源(例如您的DataTable)并在for循环中提供值。
  3. 示例

    在下面的示例中,如果从数据库加载数据,则没有任何区别。但为了提供一个最小的完整可验证示例,我自己创建了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 - 将列添加到DataTable

    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");
    

答案 1 :(得分:1)

根本不要使用 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 异步