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

[1108 byte] By [KunalYadav] at [2007-12-16]
# 1
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

KunalYadav at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 2
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"

MarkRideout at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 3
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

KunalYadav at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...
# 4
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"

MarkRideout at 2007-9-9 > top of Msdn Tech,Windows Forms,Windows Forms General...