DataGridView DefaultCellStyle Problem

Megalith

Well-known member
Joined
Aug 21, 2006
Messages
66
Programming Experience
10+
I'm working on a database program that needs to conditionally change backcolor of a cell based on the value of a cell in the same row, i spent hours searching online for a way to do this and could only find things relating to the DataGrid so i looked on MSDN and found a routine that could change background colours i modified it slightly for my data set and created a simple form with a DataGridView object on it which was bound at design time to my database. it seemed to work (after replacing column names with the column number) but i noticed a few things wrong the backcolor of the headers was still white and the backcolor of the column i changed remained unaltered. Heres the code in my form 1, can anybody see what i have done wrong and does anyone know how to conditionally change an individual cells backcolor property?
VB.NET:
Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'TODO: This line of code loads data into the 'HandHistoryDataSet.HoldEm' table. You can move, or remove it, as needed.
        InitializeDataGridView()
        Me.HistoryTableAdapter.Fill(Me.HistoryDataSet.HoldEm)

    End Sub

    ' Configures the appearance and behavior of a DataGridView control.
    Private Sub InitializeDataGridView()

        ' Initialize basic DataGridView properties.
        dataGridView1.Dock = DockStyle.Fill
        dataGridView1.BackgroundColor = Color.LightGray
        DataGridView1.BorderStyle = BorderStyle.Fixed3D

        ' Set property values appropriate for read-only display and 
        ' limited interactivity. 
        dataGridView1.AllowUserToAddRows = False
        dataGridView1.AllowUserToDeleteRows = False
        dataGridView1.AllowUserToOrderColumns = True
        dataGridView1.ReadOnly = True
        dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect
        dataGridView1.MultiSelect = False
        dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None
        dataGridView1.AllowUserToResizeColumns = False
        dataGridView1.ColumnHeadersHeightSizeMode = _
            DataGridViewColumnHeadersHeightSizeMode.DisableResizing
        dataGridView1.AllowUserToResizeRows = False
        dataGridView1.RowHeadersWidthSizeMode = _
            DataGridViewRowHeadersWidthSizeMode.DisableResizing

        ' Set the selection background color for all the cells.
        dataGridView1.DefaultCellStyle.SelectionBackColor = Color.White
        dataGridView1.DefaultCellStyle.SelectionForeColor = Color.Black

        ' Set RowHeadersDefaultCellStyle.SelectionBackColor so that its default
        ' value won't override DataGridView.DefaultCellStyle.SelectionBackColor.
        DataGridView1.RowHeadersDefaultCellStyle.SelectionBackColor = Color.Empty

        ' Set the background color for all rows and for alternating rows. 
        ' The value for alternating rows overrides the value for all rows. 
        dataGridView1.RowsDefaultCellStyle.BackColor = Color.LightGray
        dataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.DarkGray

        ' Set the row and column header styles.
        dataGridView1.ColumnHeadersDefaultCellStyle.ForeColor = Color.White
        DataGridView1.ColumnHeadersDefaultCellStyle.BackColor = Color.Black
        DataGridView1.RowHeadersDefaultCellStyle.BackColor = Color.Black

        ' change the foreground and background color of this column
        DataGridView1.Columns(1).DefaultCellStyle.ForeColor = Color.Red
        DataGridView1.Columns(1).DefaultCellStyle.BackColor = Color.AliceBlue

        ' Specify a larger font for the "Ratings" column. 
        Dim font As New Font( _
            DataGridView1.DefaultCellStyle.Font.FontFamily, 14, FontStyle.Bold)
        Try
            DataGridView1.Columns(14).DefaultCellStyle.Font = font
        Finally
            font.Dispose()
        End Try

    End Sub

End Class
I read in my research that this could only be done thru a paint method but the source of my info was pre .NET 2, MSDN appears to indicate it is possible to conditionally change cells.
 
Last edited:
I've done some more research on MSDN and it would seem that the only way to do this is through a CellPaint event, i scrapped the above code and am now using the paint event to obtain my desired result. however i am still having the problem with the named columns in that even if i cut and paste them so they are exactly the same i get this error

System.NullReferenceException was unhandled by user code
Message="Object reference not set to an instance of an object."
Source="Cell Colours"


if i replace the name with the column number then i dont get this error. am i missing something heres an example code using the NorthWnd database
VB.NET:
Imports system.windows.forms
Imports System.Drawing

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'TODO: This line of code loads data into the 'NORTHWNDDataSet.Customers' table. You can move, or remove it, as needed.
        Me.CustomersTableAdapter.Fill(Me.NORTHWNDDataSet.Customers)

    End Sub

    Private Sub dataGridView1_CellPainting(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) _
    Handles DataGridView1.CellPainting

        If Me.DataGridView1.Columns("ContactName").Index = _
           e.ColumnIndex AndAlso e.RowIndex >= 0 Then
            If DataGridView1.Item(5, e.RowIndex).Value = "London" Then
                Dim newRect As New Rectangle(e.CellBounds.X + 1, e.CellBounds.Y + 1, _
                    e.CellBounds.Width - 4, e.CellBounds.Height - 4)
                Dim backColorBrush As New SolidBrush(e.CellStyle.BackColor)
                Dim gridBrush As New SolidBrush(Me.DataGridView1.GridColor)
                Dim gridLinePen As New Pen(gridBrush)

                Try

                    ' Erase the cell.
                    e.Graphics.FillRectangle(backColorBrush, e.CellBounds)

                    ' Draw the grid lines (only the right and bottom lines;
                    ' DataGridView takes care of the others).
                    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, _
                        e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, _
                        e.CellBounds.Bottom - 1)
                    e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1, _
                        e.CellBounds.Top, e.CellBounds.Right - 1, _
                        e.CellBounds.Bottom)

                    ' Draw the inset highlight box.
                    e.Graphics.DrawRectangle(Pens.BurlyWood, newRect)

                    ' Draw the text content of the cell, ignoring alignment.
                    If (e.Value IsNot Nothing) Then
                        e.Graphics.DrawString(CStr(e.Value), e.CellStyle.Font, _
                        Brushes.Crimson, e.CellBounds.X + 2, e.CellBounds.Y + 2, _
                        StringFormat.GenericDefault)
                    End If
                    e.Handled = True

                Finally
                    gridLinePen.Dispose()
                    gridBrush.Dispose()
                    backColorBrush.Dispose()
                End Try

            End If
        End If
    End Sub

End Class

the form has a DataGridView control on it set at design to connect to the Customers table of the NorthWnd database.

if the "ContactName" string is replaced with 2 the routine works fine??
 
That looks interesting :) i've managed to implement a percentage bar into the cells in certain columns using the paintcell event but i am presuming this is hogging resources on my application. I'll look thru that article and implement this as well as i have several columns it would be appropriate for.

I managed to get rid of the problem i was having with column labels, i dont know what exactly was wrong but i deleted all the columns from the datagridview edit columns feature and replaced them all, the problem vanished so i guess the auto fill of this object is buggy.
 
Back
Top