Question DataGridview: keep row style upon sort

Lotok

Well-known member
Joined
Jan 17, 2012
Messages
198
Location
Scotland
Programming Experience
5-10
I have a datagrid control on a winform. During the process of data manipulation, via form button presses, the code will highlight some Cells (ones containing errors).

when an error is detected I have an arraylist of string arrays. My initial thinking was to input the row index and column name in the array which works ok until the datagrid column is clicked to sort. At that time the indexes all change and the wrong cells remain highlighted.

I am looking for ideas on how to track the index change so I can move the highlighted cell accordingly.

Here is the code for colouring the cell

 
    Private Sub dgMain_CellFormatting(sender As Object, e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgMain.CellFormatting
        For i = 0 To arrErrors.Count - 1 Step 1
            Dim r() As String = arrErrors(i)
            Dim rw As DataGridViewRow = dgMain.Rows(r(0))
            rw.Cells(r(1)).Style.BackColor = Color.Red
        Next
        updateStatus(arrErrors.Count & " Errors")
    End Sub

 
I was looking at things linked directly to the cells, such Tag property and the built in error notification, the ErrorText property, but unfortunately such user properties are reset when grid is sorted.
One way to do this could be to have a non-visible column where for each row you store for example comma-separated list of columns to format.
Also note the warning in documentation about processing in CellFormatting event handler, since you are not formatting based on dynamic cell values perhaps it is better to format inline and reformat for example from Sorted event.
 
I decided to take a different approach with this. The fields that are edited all start out as 'TBC' in the value, the app will then populate them with proper values. If an error occurs then they remain TBC as the catch will kick in before the code has a chance to try and do the final edit. With that in mind, I decided to highlight the field based on value. If it says TBC then it has an error, therefore show red.

my code changed to

VB.NET:
[FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]Private[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]Sub[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] dgMain_CellFormatting(sender [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]Object[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2], e [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]As[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] System.Windows.Forms.[/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#2b91af][FONT=Consolas][SIZE=2][COLOR=#2b91af][FONT=Consolas][SIZE=2][COLOR=#2b91af]DataGridViewCellFormattingEventArgs[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2]) [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]Handles[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] dgMain.CellFormatting
[/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#008000][FONT=Consolas][SIZE=2][COLOR=#008000][FONT=Consolas][SIZE=2][COLOR=#008000]'colour error cells
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]If[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]CStr[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2](e.Value) = [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#a31515][FONT=Consolas][SIZE=2][COLOR=#a31515][FONT=Consolas][SIZE=2][COLOR=#a31515]"TBC"[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]Then
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2]e.CellStyle.BackColor = [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#2b91af][FONT=Consolas][SIZE=2][COLOR=#2b91af][FONT=Consolas][SIZE=2][COLOR=#2b91af]Color[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2].Red
[/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]If
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2][/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]End[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][FONT=Consolas][SIZE=2][FONT=Consolas][SIZE=2] [/SIZE][/FONT][/SIZE][/FONT][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff][FONT=Consolas][SIZE=2][COLOR=#0000ff]Sub
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT]

I was not aware of the problems processing in CellFormatting. I will read up on it. I just started a new job where I will be using VB a lot, just re-aquainting myself with it really. I havent developed much over the last few years so will be out of touch. Thanks for the heads up.
 
Why don't you just use the built in functions for this? Google:
Datagridviewrow error
Datagridviewcell error

for more info
 
Why don't you just use the built in functions for this? Google:
Datagridviewrow error
Datagridviewcell error

for more info
I would too, perhaps, but you'd still have to reprocess after sorting:
me said:
I was looking at things linked directly to the cells, such Tag property and the built in error notification, the ErrorText property, but unfortunately such user properties are reset when grid is sorted.
 
There doesn't seem to be much overhead doing what I coded (see #3) and it does whats needed so will leave be, even if its considered a little dirty. :)
 
Darn shame.. Now I'm on a PC I can verify that yep.. The DGV recreates all its rows when sorted..

In which case I recommend you latch onto the DataTable.RowChanged event, check all the values and set the RowError text:

VB.NET:
Dim ro as DataRow = e.Row
ro.RowError = ""
If ro.Item(1).ToString() = "0" Then
  ro.RowError += "Blah column cannot be zero, "
End If
If DirectCast(ro.Item(2), DateTime) > DateTime.Now() Then
  ro.RowError += "OtherBlah date must be in the past, "
End If
ro.RowError = ro.RowError.TrimEnd(" "c,","c)
If string.IsNullOrEmpty(ro.RowError) Then
  ro.RowError = Nothing
End If

Now your grid will have a red exclamation mark in the row header for that row if anything violates rules. It can be sorted and it persists. Pointing to it gives the error message
 
Darn shame.. Now I'm on a PC I can verify that yep.. The DGV recreates all its rows when sorted..

In which case I recommend you latch onto the DataTable.RowChanged event, check all the values and set the RowError text:

VB.NET:
Dim ro as DataRow = e.Row
ro.RowError = ""
If ro.Item(1).ToString() = "0" Then
  ro.RowError += "Blah column cannot be zero, "
End If
If DirectCast(ro.Item(2), DateTime) > DateTime.Now() Then
  ro.RowError += "OtherBlah date must be in the past, "
End If
ro.RowError = ro.RowError.TrimEnd(" "c,","c)
If string.IsNullOrEmpty(ro.RowError) Then
  ro.RowError = Nothing
End If

Now your grid will have a red exclamation mark in the row header for that row if anything violates rules. It can be sorted and it persists. Pointing to it gives the error message

Thanks very much for this, I will take a look at that today, looks likea pretty simple and effective solution. :)
 
Back
Top