DataGridView CellFormatting性能问题
本文关键字:问题 性能 CellFormatting DataGridView | 更新日期: 2023-09-27 18:05:48
如何修复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());
}
如果性能问题是由于Decrypt
方法,您应该避免在CellFormatting
中使用它,如事件文档的备注部分所述:
每次绘制每个单元格时都会发生
CellFormatting
事件,因此在处理此事件时,应避免冗长的处理。
我可以使用什么解决方案来基于第一列为第二列提供值?
您可以使用以下两个选项之一:
- 为
DataGridView
添加第二列,并在for循环中提供值。 - 为数据源添加第二列(例如
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 -在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");
不要使用 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();
正如您从代码中看到的,关键是在应用Data Source
之后和ResumeLayout
方法之前更改CellFormating
。
试试吧,你会对结果满意的。
哦!并确保在 BeginInvoke((Action)(() => { // Some code });
代码中执行此操作。所以请异步获取并准备Data Source