Link to home
Start Free TrialLog in
Avatar of webkiwi1
webkiwi1

asked on

Changing datagridview row colors at runtime

Hello experts,

VS2005/VB.Net

I am buidling a datagridview with data retreived from SQL queries. As data is gathered I am adding rows to the datagridview using:

                'Header row
                Dim row As String() = {"Useless information here"}
                DataGridView1.Rows.Add(row)

-or-

            ' Add row with multiple columns of data
            Dim row As String() = {"Here it is", Data1, Data2, Data3, Data4, Data5}
            DataGridView1.Rows.Add(row)

I would LOVE to be able to change the background color and or font on certain rows as they are added, for example make the header row blue so they stand out a little better.

Thanks,
Michael
Avatar of VBRocks
VBRocks
Flag of United States of America image

You can change the background color of the column headers like this:

        Me.DataGridView1.ColumnHeadersDefaultCellStyle.BackColor = Color.Blue
        Me.DataGridView1.ColumnHeadersDefaultCellStyle.ForeColor = Color.White

To setup alternating colors, you can do it like this:

        Me.DataGridView1.RowsDefaultCellStyle.BackColor = Color.White
        Me.DataGridView1.AlternatingRowsDefaultCellStyle.BackColor = Color.Yellow



Avatar of webkiwi1
webkiwi1

ASKER

Thanks for the suggestions.

I was not too clear in my request as far as when I referred to Header row, I did not mean the main header row of the datagridview...sorry.

As I build the datagridview, I am adding rows that define what follows, i.e. "Useless information", and then sveral rows of stuff, and then "Important information", and another few rows of stuff, all within the same datagridview.

It is those rows (Useless, important etc.) individually I would like to assign a different color and/or fotn style (eg. bold).
Ok, you can do that.

For your DataGridView, use the RowsAdded event.  Here's an example:

    Private Sub DataGridView1_RowsAdded(ByVal sender As System.Object, _
        ByVal e As System.Windows.Forms.DataGridViewRowsAddedEventArgs) _
        Handles DataGridView1.RowsAdded

        'Setup all of the styles you want here
        Dim style1 As New System.Windows.Forms.DataGridViewCellStyle
        style1.BackColor = Color.Blue
        style1.ForeColor = Color.White

        Dim style2 As New System.Windows.Forms.DataGridViewCellStyle
        style2.BackColor = Color.Yellow
        style2.ForeColor = Color.Blue
        'End of styles


        'Loop through all of the rows that were added,
        '  check the value of whatever column you want
        '  change the cellstyle for that row
        Dim row As DataGridViewRow

        'Index of first row added
        For idx As Int32 = e.RowIndex To e.RowCount - 1

            row = Me.DataGridView1.Rows(idx)

            If row.Cells(0).Value IsNot Nothing Then
                If row.Cells(0).Value.ToString() = "1" Then
                    row.DefaultCellStyle = style1

                Else
                    row.DefaultCellStyle = style2
                End If
            End If

        Next

    End Sub

Awesome, I will try it right now...
VBRocks, I tried the routine and it worked for the first row added, but does not work from there on out.

When the first row is added it assigns the value idx=0 and then goes through the If statement.
When the second and subsequent rows are added it jumps from the For idx to End sub and skips the If statement.

Any ideas?

idx has no value for rows 2+ but the e.rowindex increments with each row.
When you form loads, that event will actually get fired several times.  The first time it is fired when the
grid loads columns, and then it is fired again as the grid configures.

The final time the event is called, it will loop through all of the code and format as specified.

I tried the same exact code, no modifications, add it changed the style for any row that met the criteria.

What you want to look at is e.RowIndex and e.RowCount.
    e.RowIndex returns the index of the first row that was added.
    e.RowCount returns the number of rows that were added.


Does it make a difference if the datagridview is hidden when the form loads?
VBRocks, I have played around with this and can not get it to work. Same as explained above. I am adding rows in different places of code (sometimes 4 at a time, sometimes only 1 or two), and the DataGridView1_RowsAdded sub only applies the background color change to the very first row added to the datagridview. .
Sorry, just got back from the DMV...  Let me take a look.
Ok, well...  Sorry.  I guess I'm not going to be able to help you, because it's running perfect for me.  :(

One change I made was to search for a cell value that had a "3" in it, and it selected a lot of rows for me
(I didn't count)...  So maybe it has to do with the way your are searching?

        'Loop through all of the rows that were added,
        '  check the value of whatever column you want
        '  change the cellstyle for that row
        Dim row As DataGridViewRow

        'Index of first row added
        For idx As Int32 = e.RowIndex To e.RowCount - 1

            row = Me.DataGridView1.Rows(idx)

            If row.Cells(0).Value IsNot Nothing Then

                '* Changed this search search the cell value for "3"
                If row.Cells(0).Value.ToString().IndexOf("3") > -1 Then
                    row.DefaultCellStyle = style1

                Else
                    row.DefaultCellStyle = style2
                End If
            End If

        Next



I think the problem might lie in how I am adding the rows, or where/when I am adding them.

Do you have a sample with this code and a datagridview that you are addings several rows two that you can post or maybe email so I can look at how the rows are being added?

My code has multiple sql calls that would be too confusing to sift through to test!

Thanks for trying  :)
Sure, I'd be happy to.

Add a new form to your project, and add a DataGridView to the form, name it "DataGridView1"
Double-Click on the form and add the code below, be sure to change the form name of "Form1" in the
"Form1_Load" event to whatever the name of your form is.

'This code will highlight every row that has a Quantity (Qty) of "3":

    Private Sub Form1_Load(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.Load

        'Create a table and set it as the DataSource for the DataGridView
        Dim table As New DataTable()
        table.Columns.Add("Item")
        table.Columns.Add("Qty")

        'Add the same data 5 times so there will be 5 rows that match
        For iSets As Int16 = 1 To 5

            'Loop and add rows to table
            For i As Int16 = 1 To 5
                table.Rows.Add("Item " & i.ToString, i)
            Next

        Next

        Me.DataGridView1.DataSource = table

    End Sub



    Private Sub DataGridView1_RowsAdded(ByVal sender As System.Object, _
        ByVal e As System.Windows.Forms.DataGridViewRowsAddedEventArgs) _
        Handles DataGridView1.RowsAdded

        'Setup all of the styles you want here
        Dim style1 As New System.Windows.Forms.DataGridViewCellStyle
        style1.BackColor = Color.Red
        style1.ForeColor = Color.Yellow

        Dim style2 As New System.Windows.Forms.DataGridViewCellStyle
        style2.BackColor = Color.White
        style2.ForeColor = Color.Black
        'End of styles


        'Loop through all of the rows that were added,
        '  check the value of whatever column you want
        '  change the cellstyle for that row
        Dim row As DataGridViewRow


        '*** Set to the name of the column to search ***
        Dim columnName As String = "Qty"

        '*** Set to the value to search for ***
        Dim searchCriteria As String = "3"

        'Index of first row added
        For idx As Int32 = e.RowIndex To e.RowCount - 1

            row = Me.DataGridView1.Rows(idx)

            'Make sure the column exists, and IsNot Nothing
            If Me.DataGridView1.Columns.Contains(columnName) = True AndAlso _
                row.Cells(columnName).Value IsNot Nothing Then

                'Search the Qty column for all cells with a value of 3
                If row.Cells(columnName).Value.ToString() = searchCriteria Then
                    row.DefaultCellStyle = style1

                Else
                    row.DefaultCellStyle = style2
                End If

            End If

        Next

    End Sub




Just a note, I tweeked the code just a bit, but not enough to make a different with the problem you
are having.

The big difference I see is you are adding data to the data table, and then adding it all at once to the datagridview, whereas I am adding rows directly to the datagridview one at a time...

I will rework my code and try your method and see if it works...makes sense!
Well, if you are adding them 1 at a time, then set the style as you add them.  Let me whip up an
example for you...

ASKER CERTIFIED SOLUTION
Avatar of VBRocks
VBRocks
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Sorry, did not get a chance to acdept solution...worked perfectly.
Thanks.