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:

  1. Name or index of the column.
  2. 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

enter image description 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;
    }
  }
}