Datagridview single cell color

TaleOfTimes

Newcomer
Joined
Dec 20, 2005
Messages
15
Hello all,

this is pissing me off. I want to change the style of a single cell in a datagridview control. I'm using this

datagridview1.Rows[0].Cells["Column1"].Style.Backcolor = Color.Blue;

no compilation errors, but then at runtime it completely ignores it and keeps the background color white. The only way I can get anything to happen is by settings the DefaultCellStyle on the column, but I dont want to change the entire column, just ONE cell

thanks
 
Ok I found the problem. I have a databinding on the datagridview. When I use AcceptChanges on a table in the dataset it erases the cell styles. Why?
 
I just finished doing this exact thing. You need to make a special class to repaint the cell, and also call it in the program for the datagrid. Here is my code you can look at and hopefully this will help get you started. In the Class ColoredTextBoxColumnResult is where you do the comparison to change the color of the cell. You see mine, but I am sure you will have different comparisons. But I left mine in there as an example.

You can also read this to give you a better explanation of why it is done this way http://msdn2.microsoft.com/en-us/library/aa289506(VS.71).aspx

this routine formats the columns for the colors. Calls from the class I put in below.

When I set up everything say at load. You need to call like so.
Visual Basic:
me.FormatGridColumns()
me.CompleteDataGrid()

Visual Basic:
Private Sub FormatGridColumns()
        Me.datResult.TableStyles.Clear()
        Dim tsProducts As New DataGridTableStyle
        Dim tbcChan As DataGridTextBoxColumn
        Dim ctbcResult(12) As ColoredTextBoxColumnResult
        Dim intLoop As Integer
        tbcChan = New DataGridTextBoxColumn
        With tbcChan
            .MappingName = "Channels"
            .HeaderText = "Channels"
            .Width = 100
            .Alignment = HorizontalAlignment.Center
        End With
        If Me.PT.arryFreqs.Count <> 0 Then
            For intLoop = 1 To Me.PT.arryFreqs.Count
                ctbcResult(intLoop) = New ColoredTextBoxColumnResult
                With ctbcResult(intLoop)
                    .MappingName = "freq" & intLoop.ToString
                    .HeaderText = Me.PT.arryFreqs.Item(intLoop - 1)
                    .Width = 100
                    .Alignment = HorizontalAlignment.Center
                End With
            Next
        End If
        tsProducts.MappingName = "results"
        tsProducts.GridColumnStyles.Add(tbcChan)
        If Me.PT.arryFreqs.Count <> 0 Then
            For intLoop = 1 To Me.PT.arryFreqs.Count
                tsProducts.GridColumnStyles.Add(ctbcResult(intLoop))
            Next
        End If
        Me.datResult.TableStyles.Add(tsProducts)
        tsProducts.Dispose()
    End Sub


Set up my datagrid
Visual Basic:
Private Sub CompleteDataGrid()
        Me.datResult.DataSource = Nothing
        Me.datResult.CaptionText = "Results in dB"
        Dim objCellVal As Object
        Dim intL As Integer
        Dim intLC As Integer
        Dim strR As String
        Dim dt As New DataTable
        Dim dr As DataRow
        Dim dv As DataView = New DataView
        With dt
            .TableName = "results"
            .Columns.Add("Channels")
            For intL = 1 To PT.arryFreqs.Count
                .Columns.Add("freq" & intL.ToString)
            Next
        End With
        With dv
            .Table = dt
            For intL = 1 To PT.arryChansTested.Count
                dr = .Table.NewRow
                .Table.Rows.Add(dr)
            Next
        End With
        With Me.datResult
            .DataSource = dv
            For intL = 0 To (PT.arryChansTested.Count - 1)
                For intLC = 0 To (PT.arryFreqs.Count)
                    If intLC = 0 Then
                        strR = PT.arryChansTested(intL)
                        objCellVal = strR.Substring(0, strR.IndexOf(":"))
                    Else
                        objCellVal = 0
                    End If
                    .Item(intL, intLC) = objCellVal
                Next
            Next
        End With
    End Sub



repaint class
Visual Basic:
Public Class ColoredTextBoxColumnResult
    Inherits DataGridTextBoxColumn
    Dim passthruVar As PassThru
    Protected Overloads Overrides Sub Paint(ByVal graph As Graphics, _
         ByVal rectbounds As Rectangle, ByVal curmngrSrc As _
         CurrencyManager, ByVal RowNumber As Integer, ByVal _
         ForeColorBrush As Brush, ByVal BackColorBrush As Brush, _
         ByVal AlignmentRight As Boolean)

        Dim ObjVal As Object
        ObjVal = Me.GetColumnValueAtRow(curmngrSrc, RowNumber)
        If Not (IsNothing(ObjVal) Or IsDBNull(ObjVal)) Then
            If IsNumeric(ObjVal) Then
                Dim dblUL As Double
                Dim strMap As String = Me.MappingName
                Dim cellValue As Double = Convert.ToDouble(ObjVal)
                Dim intCol As Integer = Convert.ToInt32(strMap.Substring(strMap.IndexOf("q") + 1))
                If intCol <> 0 Then
                    dblUL = Convert.ToDouble(Me.passthruVar.arryDBs(intCol - 1))
                End If
                If dblUL > 0 Then
                    dblUL = (dblUL * -1)
                End If
                If cellValue = 0 Then
                    BackColorBrush = Brushes.LightGray
                    ForeColorBrush = Brushes.Black
                ElseIf (cellValue > dblUL) Or (cellValue < -90) Then
                    BackColorBrush = Brushes.Red
                    ForeColorBrush = Brushes.Black
                Else
                    BackColorBrush = Brushes.Green
                    ForeColorBrush = Brushes.Black
                End If
            Else
                BackColorBrush = Brushes.Gray
                ForeColorBrush = Brushes.Black
            End If
        Else
            BackColorBrush = Brushes.Gray
            ForeColorBrush = Brushes.Black
        End If


        ' Call Paint from the base class to 
        ' accomplish the actual drawing.
        MyBase.Paint(graph, rectbounds, curmngrSrc, RowNumber, _
            BackColorBrush, ForeColorBrush, AlignmentRight)
    End Sub
 
Thanks for the reply!

I also found that putting
datagridview1.Rows[e.RowIndex].Cells["Column1"].Style.Backcolor = Color.Blue;
in the RowPostPaint event also gets the job done although it is not the most efficient way.

Thank again
 
Hmm. I was looking in my applications and realized I don't have the datagridview1. Are you running 2005 version? I am running VS 2003 version. That is probably why I needed to make that class.
 
Back
Top