Changing datagridview cell color based on condition
Kyle's and Simon's answers are gross waste of CPU resources. CellFormatting
and CellPainting
events occur far too many times and should not be used for applying styles. Here are two better ways of doing it:
If your DataGridView or at least the columns that decide cell style are read-only, you should change DefaultCellStyle of rows in RowsAdded
event. This event occurs only once when a new row is added. The condition should be evaluated at that time and DefaultCellStyle
of the row should be set therein. Note that this event occurs for DataBound situations too.
If your DataGridView or those columns allow editing, you should use CellEndEdit
or CommitEdit
events to change DefaultCellStyle
.
You need to do this
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
foreach (DataGridViewRow Myrow in dataGridView1.Rows)
{ //Here 2 cell is target value and 1 cell is Volume
if (Convert.ToInt32(Myrow .Cells[2].Value)<Convert.ToInt32(Myrow .Cells[1].Value))// Or your condition
{
Myrow .DefaultCellStyle.BackColor = Color.Red;
}
else
{
Myrow .DefaultCellStyle.BackColor = Color.Green;
}
}
}
Meanwhile also take a look at Cell Formatting
I may suggest NOT looping over each rows EACH time CellFormating is called, because it is called everytime A SINGLE ROW need to be refreshed.
Private Sub dgv_DisplayData_Vertical_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles dgv_DisplayData_Vertical.CellFormatting
Try
If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "6" Then
e.CellStyle.BackColor = Color.DimGray
End If
If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "5" Then
e.CellStyle.BackColor = Color.DarkSlateGray
End If
If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "4" Then
e.CellStyle.BackColor = Color.SlateGray
End If
If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "3" Then
e.CellStyle.BackColor = Color.LightGray
End If
If dgv_DisplayData_Vertical.Rows(e.RowIndex).Cells("LevelID").Value.ToString() = "0" Then
e.CellStyle.BackColor = Color.White
End If
Catch ex As Exception
End Try
End Sub
Let's say you have to color certain cell (not all cells of the row) by knowing two things:
- Name or index of the column.
- Value which is gonna be inside of the cell.
In thas case you have to use event CellFormatting
In my case I use like this
private void DgvTrucksMaster_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
foreach (DataGridViewRow row in dgvTrucksMaster.Rows)
{
if (Convert.ToInt32(row.Cells["Decade1Hours"].Value) > 0)
{
row.Cells["Decade1Hours"].Style.BackColor = Color.LightGreen;
}
else if (Convert.ToInt32(row.Cells["Decade1Hours"].Value) < 0)
{
// row.DefaultCellStyle.BackColor = Color.LightSalmon; // Use it in order to colorize all cells of the row
row.Cells["Decade1Hours"].Style.BackColor = Color.LightSalmon;
}
}
}
And result you can see here
So here you can access certain cell of the row in column by its name row.Cells["Decade1Hours"]
How do you know this name? Well in my case i create column of DataGridView like this.
var Decade1Hours = new DataGridViewTextBoxColumn()
{
Name = "Decade1Hours",
Width = 50,
DataPropertyName = "Decade1Hours",
ReadOnly = true,
DefaultCellStyle = new DataGridViewCellStyle()
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
ForeColor = System.Drawing.Color.Black,
Font = new Font(font, FontStyle.Bold),
Format = "n2"
},
HeaderCell = new DataGridViewColumnHeaderCell()
{
Style = new DataGridViewCellStyle()
{
Alignment = DataGridViewContentAlignment.MiddleCenter,
BackColor = System.Drawing.Color.Blue
}
}
};
Decade1Hours.HeaderText = "Дек.1";
dgvTrucksMaster.Columns.Add(Decade1Hours);
And well... you you need for instance colorize some of the cells in the row like ##1 4 5 and 8 you have to use cell index (it starts from 0).
And code will lok like
private void DgvTrucksMaster_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
foreach (DataGridViewRow row in dgvTrucksMaster.Rows)
{
if (Convert.ToInt32(row.Cells[1].Value) > 0 )
{
row.Cells[1].Style.BackColor = Color.LightGreen;
}
}
}