X11 X11 - 2 months ago 24
C# Question

DataGridView CellFormatting performance issue

How to fix

CellFormatting
"slow scrolling" performance issue?

I use this code to copy decrypted values from encrypted column to another column:

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());
}

Answer

If the performance issue is because of Decrypt method, you should avoid using it in CellFormatting as mentioned in remarks part of the event's documentations:

The CellFormatting event occurs every time each cell is painted, so you should avoid lengthy processing when handling this event.

what solution can I use to provide value for the second column based on first column?

You can use either of these options:

  1. Add second column to DataGridView and provide the value in a for loop.
  2. Add second column to your data source (for example your DataTable) and provide the value in a for loop.

Example

In the below example, it doesn't make any difference if you load data from database. But to provide a minimal complete verifiable example, I created DataTable myself. In both examples LoadData method, loads a 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;
}

Example 1 - Add Column To 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());
}

Example 2 - Add Column to 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");
Comments