Reputation: 12283
I'm painting my rows in a DataGridView like this:
private void AdjustColors()
{
foreach (DataGridViewRow row in aufgabenDataGridView.Rows)
{
AufgabeStatus status = (AufgabeStatus)Enum.Parse(typeof(AufgabeStatus), (string)row.Cells["StatusColumn"].Value);
switch (status)
{
case (AufgabeStatus.NotStarted):
row.DefaultCellStyle.BackColor = Color.LightCyan;
break;
case (AufgabeStatus.InProgress):
row.DefaultCellStyle.BackColor = Color.LemonChiffon;
break;
case (AufgabeStatus.Completed):
row.DefaultCellStyle.BackColor = Color.PaleGreen;
break;
case (AufgabeStatus.Deferred):
row.DefaultCellStyle.BackColor = Color.LightPink;
break;
default:
row.DefaultCellStyle.BackColor = Color.White;
break;
}
}
}
Then I call it in the OnLoad method:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
AdjustColors();
}
I prefer OnLoad to OnPaint or something.. because OnPaint is called very often.
The question: Why does it take about 100 - 200 ms to change the background of every row? Early, I was doint CellPaint.. but I had problems when scrolling with refreshing..
Upvotes: 12
Views: 8554
Reputation: 13025
Instead of changing the color of the whole DataGrid
at once, you should let it manage the rendering by overriding the CellFormatting
event. The rows will only be painted when they are actually displayed on the screen.
private void aufgabenDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridViewRow row = aufgabenDataGridView.Rows[e.RowIndex];
AufgabeStatus status = (AufgabeStatus) Enum.Parse(typeof(AufgabeStatus), (string) row.Cells["StatusColumn"].Value);
switch (status)
{
case (AufgabeStatus.NotStarted):
e.CellStyle.BackColor = Color.LightCyan;
break;
case (AufgabeStatus.InProgress):
e.CellStyle.BackColor = Color.LemonChiffon;
break;
case (AufgabeStatus.Completed):
e.CellStyle.BackColor = Color.PaleGreen;
break;
case (AufgabeStatus.Deferred):
e.CellStyle.BackColor = Color.LightPink;
break;
default:
e.CellStyle.BackColor = Color.White;
break;
}
}
If this is still too slow, try getting the real object the row is bound to:
...
DataGridViewRow row = aufgabenDataGridView.Rows[e.RowIndex];
var aufgabe = (Aufgabe) row.DataBoundItem;
AufgabeStatus status = aufgabe.Status;
...
Upvotes: 17
Reputation: 1
don't try row format as row.defaultcellstyle
try individual cell formatting in ufgabenDataGridView_CellFormatting
cell[0].style.backcolor=color.yellow
Upvotes: 0
Reputation: 21
It's also a good idea to only set the properties if they differ from the expected value. That way you don't trigger unwanted internal DataGridView overhead.
If all cells in a row are formatted the same way, you can do the formatting on row level instead of cell level.
DataGridViewCellStyle rowStyle = row.DefaultCellStyle;
if (rowStyle.BackColor != status.BackColor) {
rowStyle.BackColor = status.BackColor;
}
Upvotes: 2
Reputation: 49261
As SwDevMan1 said, you should first work on removing the Enum.Parse call. Are you using data binding to populate the grid? If so, you can use Rows[index].DataBoundItem to access the data bound object for the row and access the AufgabeStatus status directly.
The second tweak I would suggest is to call SuspendLayout() and ResumeLayout() before and after, respectively, manipulating the grid.
Upvotes: 2
Reputation: 49988
Its probably the Enum.Parse call, it has poor performance. You should try and change it to a dictionary lookup to see if that improves performance. See this post
Upvotes: 2