VB.Net Sort datagridview rows by color

Hi Experts.    I have a search function on a datagridview that changes the backcolor of the row depending on the search criteria.  Anyone know how to get all the coloured rows to the top of the datagridview?   Many thanks
LVL 2
PNRTAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Robert SchuttSoftware EngineerCommented:
Here is a little test project. Just a form with a textbox and a datagridview and the following code:
Public Class Form1

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        DataGridView1.Columns.Add("col1", "id")
        DataGridView1.Columns.Add("col2", "name")
        For i As Integer = 1 To 100
            DataGridView1.Rows.Add(i, "Row " & i)
        Next
    End Sub

    Private Sub TextBox1_TextChanged(sender As System.Object, e As System.EventArgs) Handles TextBox1.TextChanged
        For i As Integer = 0 To DataGridView1.Rows.Count - 1
            If TextBox1.Text <> "" AndAlso DataGridView1.Rows(i).Cells(1).Value.ToString.Contains(TextBox1.Text) Then
                DataGridView1.Rows(i).DefaultCellStyle.BackColor = Color.LightGreen
            Else
                DataGridView1.Rows(i).DefaultCellStyle.BackColor = Color.White
            End If
        Next
        DataGridView1.Sort(New ColorComparer({Color.LightGreen, Color.White}))
    End Sub

    ' source: https://msdn.microsoft.com/en-us/library/wstxtkxs(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
    Private Class ColorComparer
        Implements System.Collections.IComparer

        Private _arrColors() As Color

        Public Sub New(ByVal arrColors() As Color)
            _arrColors = arrColors
        End Sub

        Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
            Implements System.Collections.IComparer.Compare

            Dim DataGridViewRow1 As DataGridViewRow = CType(x, DataGridViewRow)
            Dim DataGridViewRow2 As DataGridViewRow = CType(y, DataGridViewRow)

            Dim CompareResult As Integer = Math.Sign(Array.IndexOf(_arrColors, DataGridViewRow1.DefaultCellStyle.BackColor) - Array.IndexOf(_arrColors, DataGridViewRow2.DefaultCellStyle.BackColor))

            ' If the colors are equal, sort based on the ID (numerically)
            If CompareResult = 0 Then
                CompareResult = Math.Sign(Convert.ToInt32(DataGridViewRow1.Cells(0).Value) - Convert.ToInt32(DataGridViewRow2.Cells(0).Value))
            End If

            Return CompareResult
        End Function
    End Class
End Class

Open in new window

0
PNRTAuthor Commented:
Thanks for the reply.  I couldn't get this working as the rows in the DGV are different colours based on their values which change all the time.  The solution compares to white.   I was hoping for something more like the ability to place rows by colour as opposed to sorting.  Thanks again
0
Robert SchuttSoftware EngineerCommented:
Please elaborate, what do you mean with "place rows by colour", can you give an example?
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

PNRTAuthor Commented:
Hi Robert.  Thanks for the reply

The DGV tracks files kept in a folder.   The file name, the file extension/file type and the date it was created are shown in the DGV rows.  There are four different file extensions/types and these are shown as different colours in the DGV.    The different file extensions/types can be grouped at the top of the DGV column by clicking the column header in the normal way.
   
The user can search the DGV rows for files that match the file extension/type by date created by file name.   When a row matches all these criteria they are then highlighted in a different colour in the grid.    These different coloured rows are distributed throughout the DGV and I would like a way of getting them all to the top of the grid so that they are easily visible.

I hope this makes sense.   Thanks again for your help
0
Robert SchuttSoftware EngineerCommented:
It does make sense but I think it would be a lot easier if you can share the relevant part of the code. The description is clear but there is more than one way to implement that and what needs to be done depends on how it is implemented currently. In your case it sounds like maybe you need to override DataGridView.SortCompare to check the colors before sorting normally.
0
PNRTAuthor Commented:
This is all I do to colour the rows by type

 Private Sub DGVColour()
        For Each row As DataGridViewRow In Me.DGV1.Rows
            If Not row.IsNewRow Then
                If Not row.Cells(2).Value Is DBNull.Value Then
                    If row.Cells(2).Value Is "Type1" Then
                        row.DefaultCellStyle.BackColor = Color.LightGreen
                    End If
                    If row.Cells(2).Value Is "Type2" Then
                        row.DefaultCellStyle.BackColor = Color.Moccasin
                    End If
                    If row.Cells(2).Value Is "Error" Then
                        row.DefaultCellStyle.BackColor = Color.Red
                        row.DefaultCellStyle.ForeColor = Color.White
                    End If
                End If
            End If
        Next
 End Sub

Open in new window

0
Robert SchuttSoftware EngineerCommented:
Ok, that's good. And the searching? Must be a bit different than mine or you would lose the backcolor.

Have you looked at implementing the DataGridView.SortCompare?
0
PNRTAuthor Commented:
HI

This finds the rows with the required filetype and if the date also matches it changes the colour of the row. There maybe 250 rows in the DGV and maybe 20 that meet the parameters and have had the colour changed.    I'm trying to get those 20 rows to the top of the grid


 For Each Row As DataGridViewRow In DGV1.Rows
            If DGV1.Rows(intcount).Cells(2).Value Is messType Then
                If doDate = True Then
                    TempDate = DGV1.Rows(intcount).Cells(1).Value.ToString
                    firstDate = TempDate.Split(CChar(" "))
                    If firstDate(0) = dateSplit Then
                        TextData = DGV1.Rows(intcount).Cells(0).Value.ToString
                        TextData = TextData.Substring(0, TextSearch.Length)
                        If TextData = TextSearch Then
                            Row.DefaultCellStyle.BackColor = Color.HotPink
                        End If
                    End If
                Else
                    TextData = DGV1.Rows(intcount).Cells(0).Value.ToString
                    TextData = TextData.Substring(0, TextSearch.Length)
                    If TextData = TextSearch Then
                        Row.DefaultCellStyle.BackColor = Color.DeepPink
                    End If
                End If
            End If
      intcount = intcount + 1
  Next Row

Open in new window

0
Robert SchuttSoftware EngineerCommented:
Well that last bit of code is not completely clear to me as it contains too many unknown variables. But just taking the colors out of that you can try:
    Private Sub DGV1_SortCompare(sender As System.Object, e As System.Windows.Forms.DataGridViewSortCompareEventArgs) Handles DGV1.SortCompare

        Static arrCol() As Color = {Color.DeepPink, Color.HotPink} ' , Color.Red, Color.Moccasin, Color.LightGreen, Color.White

        Dim dgv As DataGridView = sender
        Dim col1index As Integer = Array.IndexOf(arrCol, dgv.Rows(e.RowIndex1).DefaultCellStyle.BackColor)
        Dim col2index As Integer = Array.IndexOf(arrCol, dgv.Rows(e.RowIndex2).DefaultCellStyle.BackColor)
        If col1index > -1 Or col2index > -1 Then
            If col1index = -1 Then col1index = arrCol.Length
            If col2index = -1 Then col2index = arrCol.Length
            e.SortResult = Math.Sign(col1index - col2index)
            e.Handled = col1index <> col2index
        Else
            e.Handled = False
        End If
    End Sub

Open in new window

This may have to be tweaked as it may disrupt normal sorting but as a first stab I thought it might show you what I've been talking about with the event override. So this will keep the pink lines on top (on ascending sort, and only after a click on a column header) and should show the rest as normal. Within the pink area you may want more functionality to sort those another way.
capture
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.