如何修复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 :(得分:3)
如果性能问题是由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");
答案 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
异步 。