Row Colouring in DataGridView

Hi,

I have a requirement in which I have to set the background color of a row based on a particular cell value. The code is something like this

Private Sub DataGridView1_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles DataGridView1.CellFormatting
        If DataGridView1.Columns(e.ColumnIndex).Name = "RISK_TYPE" Then
            If e.Value.ToString() = "High_Risk" Then
                DataGridView1.Rows(e.RowIndex).InheritedStyle.BackColor = Color.Red
            ElseIf e.Value.ToString() = "Med_Risk" Then
                DataGridView1.Rows(e.RowIndex).InheritedStyle.BackColor = Color.Orange
            Else
                DataGridView1.Rows(e.RowIndex).InheritedStyle.BackColor = Color.Green
            End If
            e.FormattingApplied = True
        End If
    End Sub

Thus it should set the background color of High_Risk rows to Red color, Med_risk rows to Orange color and the rest to green color. But apparently this piece of code doesnt work. Will I have to use the RowPrePaint and RowPostPaint events to do this If so then can you please post a sample code also

Thanks,
Kunal


Answer this question

Row Colouring in DataGridView

  • Randhawa

    Thanks for the answer Mark :). The bad part is that it slows down the grid loading by atleast 4-5 secs, should I be writing this code in some other event handler

    Regards,
    Kunal

  • Solarflashlights

    I tried adding the RowPrePaint and RowPostPaint events as given below. Now the problem is that my background got set to the particular color but I am not getting any foreground text on it. Can someone please tell me where I am going wrong

        Private Sub DataGridView1_RowPrePaint(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowPrePaintEventArgs) Handles DataGridView1.RowPrePaint
            e.PaintParts = False
            Dim rowBounds As New Rectangle(Me.DataGridView1.RowHeadersWidth, e.RowBounds.Top, DataGridView1.Columns.GetColumnsWidth(DataGridViewElementState.Visible) - DataGridView1.HorizontalScrollingOffset + 1, e.RowBounds.Height)
            Dim tempBrush As SolidBrush
            If DataGridView1.Rows(e.RowIndex).Cells("FDE_FRAUD_TYPE").Value = "CR_High_Risk" Then
                tempBrush = New SolidBrush(Color.Red)
            ElseIf DataGridView1.Rows(e.RowIndex).Cells("FDE_FRAUD_TYPE").Value = "CR_Med_Risk" Then
                tempBrush = New SolidBrush(Color.Orange)
            Else
                tempBrush = New SolidBrush(Color.Green)
            End If
            Try
                e.Graphics().FillRectangle(tempBrush, rowBounds)
            Catch ex As Exception
            Finally
                tempBrush.Dispose()
            End Try
        End Sub

        Private Sub DataGridView1_RowPostPaint(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowPostPaintEventArgs) Handles DataGridView1.RowPostPaint
            Dim rowBounds As New Rectangle(Me.DataGridView1.RowHeadersWidth, e.RowBounds.Top, DataGridView1.Columns.GetColumnsWidth(DataGridViewElementState.Visible) - DataGridView1.HorizontalScrollingOffset + 1, e.RowBounds.Height)
            Dim forebrush As New SolidBrush(Color.Black)
            Try
                Dim recipe As Object = DataGridView1.Rows.SharedRow(e.RowIndex).Cells.Item(2).Value
                If Not recipe Is Nothing Then
                    Dim temp As String = recipe.ToString()

                    Dim textArea As Rectangle = rowBounds
                    textArea.X = textArea.X - DataGridView1.HorizontalScrollingOffset
                    textArea.Width = textArea.Width + DataGridView1.HorizontalScrollingOffset
                    textArea.Y = textArea.Y + rowBounds.Height - e.InheritedRowStyle.Padding.Bottom
                    textArea.Height = textArea.Height - (rowBounds.Height - e.InheritedRowStyle.Padding.Bottom)
                    textArea.Height = textArea.Height / e.InheritedRowStyle.Font.Height * e.InheritedRowStyle.Font.Height
                    Dim clip As RectangleF = RectangleF.op_Implicit(textArea)
                    clip.Width = clip.Width - (DataGridView1.RowHeadersWidth + 1 - clip.X)
                    clip.X = DataGridView1.RowHeadersWidth() + 1
                    Dim oldClip As RectangleF = e.Graphics().ClipBounds()
                    e.Graphics().SetClip(clip)
                    e.Graphics().DrawString(temp, e.InheritedRowStyle.Font, forebrush, RectangleF.op_Implicit(textArea))
                    e.Graphics().SetClip(oldClip)
                End If

            Catch ex As Exception
            Finally
                forebrush.Dispose()
            End Try
            If DataGridView1.CurrentCellAddress.Y = e.RowIndex Then
                e.DrawFocus(rowBounds, True)
            End If
        End Sub


  • wywy

    You cannot set the InheritedCellStyle, you need to set the DefaultCellStyle for the row. Change your code to:

    If DataGridView1.Columns(e.ColumnIndex).Name = "RISK_TYPE" Then
       If e.Value.ToString() = "High_Risk" Then
         DataGridView1.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.Red
       ElseIf e.Value.ToString() = "Med_Risk" Then
         DataGridView1.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.Orange
       Else
         DataGridView1.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.Green
       End If
       e.FormattingApplied = True
    End If

     


    -mark
    Program Manager
    Microsoft
    This post is provided "as-is"

  • Nedster657

    This is the correct place to add this code. In RTM builds this is much faster. Note that you can add some tag information to only set the backcolor when the backcolor isn't set yet.

    -mark
    Program Manager
    Microsoft
    This post is provided "as-is"

  • Row Colouring in DataGridView