Sorting on datagridview column loses the backcolor of the selected rows

RIAS
RIAS used Ask the Experts™
on
Hi,
I have programmatic sorting on datagridview columns and the code is :

    Private Sub SortDgColumn(ByVal sender As Object, ByVal intColindex As Integer, ByVal DoSorting As Boolean)
        'Dosorting is flag to allow descending sorting on the grid columns this is used for Resetting or Selecting all fields as the datagridview should not sort if the selection column is not sorted.
        Dim int As Integer
        int = intColindex


        Me.Cursor = Cursors.WaitCursor
        Dim newColumn As DataGridViewColumn = _
               sender.Columns(int)
        Dim oldColumn As DataGridViewColumn = sender.SortedColumn

        Dim direction As ListSortDirection
        'todo
        ' If oldColumn is null, then the DataGridView is not currently sorted.
        If Not oldColumn Is Nothing Then

            ' Sort the same column again, reversing the SortOrder.
            If oldColumn Is newColumn AndAlso sender.SortOrder = _
                SortOrder.Ascending Then
                If DoSorting = True Then direction = ListSortDirection.Descending
            Else
                ' Sort a new column and remove the old SortGlyph.
                direction = ListSortDirection.Ascending
                oldColumn.HeaderCell.SortGlyphDirection = SortOrder.None
            End If
        Else
            direction = ListSortDirection.Ascending
        End If
        ' Sort the selected column.
        If IsNothing(sender.CurrentRow) Then Exit Sub


        sender.Sort(newColumn, direction)
        If direction = ListSortDirection.Ascending Then
            newColumn.HeaderCell.SortGlyphDirection = SortOrder.Ascending
        Else
            If DoSorting = True Then newColumn.HeaderCell.SortGlyphDirection = SortOrder.Descending
        End If
        Me.Cursor = Cursors.Default

    End Sub


But as soon as I sort a column I lose all the selected rows backcolor.
Any suggestions on how can I retain it?

Cheers
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2012
Top Expert 2008

Commented:
Sounds like it isn't losing the color--the DataGridView is probably changing the selected row when you sort.

Author

Commented:
Hi LearnedOne,
Yes it is indeed!! I have a contextmenu pop up on a column for that my datagridview rows have a tag.It is lost as well .
Cheers

Author

Commented:
Is there a solution for this?It is really  driving me crazy
Regards
Most Valuable Expert 2012
Top Expert 2008

Commented:
If you don't sort, do you lose the context menu?  How are you adding the context menu?  Can you trace through the code to see if there is some event that is handled, that might be unexpectedly messing you up?

Author

Commented:
Hi,
Contextmenu pop up is based on the tags of the datagridview row.Now that I sort the column on grid all my tags are lost.
 
Cheers

Author

Commented:
I have a bound datagridview.
Cheers
Most Valuable Expert 2012
Top Expert 2008

Commented:
There is something non-standard going on here, and without more detail, it would be like trying to find a needle in a haystack.

Author

Commented:
Sorry :>
The tag for the datagridview row is set on a conmtextmenu item clicked evnt :

Private Sub ContextMenuStrip1_ItemClicked(ByVal sender As Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles ContextMenuStrip1.ItemClicked
Dim i As Short
Dim NumRecordsselected As Short
Dim StrTag, Strmodified As String
Select Case sender.parent.name
Case "Dg2"
 
If ColumnCoordinate.ToString = 7 Then
Try
StrTag = Dg(1).Rows(rowindex).Cells(7).Tag(ContextMenuStrip1.Items.IndexOf(e.ClickedItem)).ToString
Strmodified = StrTag.Substring(StrTag.Length - 1)
If Strmodified = "|" Then
e.ClickedItem.Image = My.Resources.blank
Dg(1).Rows(rowindex).Cells(7).Tag(ContextMenuStrip1.Items.IndexOf(e.ClickedItem)) = StrTag.Substring(0, StrTag.Length - 1)
Else
e.ClickedItem.Image = My.Resources.Tick
Dg(1).Rows(rowindex).Cells(7).Tag(ContextMenuStrip1.Items.IndexOf(e.ClickedItem)) = StrTag & "|"
End If
For i = 0 To ContextMenuStrip1.Items.Count - 1
StrTag = Dg2.Rows(rowindex).Cells(7).Tag(i).ToString
Strmodified = StrTag.Substring(StrTag.Length - 1)
If Strmodified = "|" Then
NumRecordsselected = NumRecordsselected + 1
End If
Next
'Notify user that value is selected from the contextmenu
For i = 0 To ContextMenuStrip1.Items.Count - 1
StrTag = Dg(1).Rows(rowindex).Cells(7).Tag(i).ToString
Strmodified = StrTag.Substring(StrTag.Length - 1)

If Strmodified = "|" Then
Dg(1)(7, rowindex).Value = "Selected (" & NumRecordsselected & " of " & ContextMenuStrip1.Items.Count & ")"
Dg(1)(ColumnCoordinate, RowCoordinate).Selected = True
Dg(1)(ColumnCoordinate, RowCoordinate + 1).Selected = True
Exit For
Else
Dg(1)(7, rowindex).Value = "Selected (" & 0 & " of " & ContextMenuStrip1.Items.Count & ")"
Dg(1)(ColumnCoordinate, RowCoordinate).Selected = True
Dg(1)(ColumnCoordinate, RowCoordinate + 1).Selected = True
End If
Next
Catch ex As Exception
Exit Sub
End Try
End If
 
 
and then on  Dg2_CellMouseUp event I populate the contextmenu with the tags of the datagridview rows
Private Sub Dg2_CellMouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles Dg2.CellMouseUp
'Change the tick icon on column 0 for datagridview 1 and change the background color


If IsNothing(e) = False AndAlso e.ColumnIndex = 7 AndAlso IsDBNull(sender.CurrentCell.Value) = False Then
'If sender.CurrentCell.Value = "Select..." Then 'add context menu
If IsNothing(Dg(1).Rows(e.RowIndex).Cells(7).Tag) = False Then
' With frmBulkContext.DgBulk
ContextMenuStrip1.TopLevel = False
ContextMenuStrip1.Parent = Dg(1)
ContextMenuStrip1.Items.Clear()
For i = 0 To UBound(Dg(1).Rows(e.RowIndex).Cells(7).Tag)
StrTag = Dg(1).Rows(e.RowIndex).Cells(7).Tag(i).ToString
Strmodified = StrTag.Substring(StrTag.Length - 1)
If Strmodified = "|" Then
With ContextMenuStrip1.Items.Add((StrTag.Substring(0, StrTag.Length - 1)), My.Resources.Tick)
.Tag = i
End With
Else
With ContextMenuStrip1.Items.Add((StrTag), My.Resources.blank)
.Tag = i
End With
End If
Next
RowCoordinate = e.RowIndex
ColumnCoordinate = e.ColumnIndex
'Adjusting the position of contextmenustrip
returnValue = sender.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, False)
ContextHeight = (Dg(1).Height) - (returnValue.Y)
If (ContextMenuStrip1.Height) < ContextHeight Then
ContextMenuStrip1.Show(returnValue.X + 100, returnValue.Y)
Else
ContextMenuStrip1.Show(returnValue.X + 100, returnValue.Y - (ContextHeight + 18))
End If
ContextMenuStrip1.BringToFront()
Exit Sub
End If
End If
 
The sorting code is posted in the question.
Cheers
Most Valuable Expert 2012
Top Expert 2008

Commented:
You are manually handling the ContextMenuStrip, with the Show method, so did you trace through that code to see if the code is run to show the context menu?

Author

Commented:
Yes this line in cell mouse up event
If IsNothing(Dg(1).Rows(e.RowIndex).Cells(7).Tag) = False Then
as the tags do not exists the contextmenu does not show up
 
Cheers

 
Most Valuable Expert 2012
Top Expert 2008

Commented:
If the Tag property is false, then something is clearing that value.  How is the Tag property set?

Author

Commented:
Hi,
The tag property is set by
Dg(1).Rows(rowindex).Cells(7).Tag(ContextMenuStrip1.Items.IndexOf(e.ClickedItem)).ToString

Cheers
Commented:
sorting cleared all tag values and cell specific formatting for me as well. My formatting was based on changes to the data in the cell vs what was originally loaded. I tried to keep track via tags but that doesnt work obviously. What I did was this:

        Dim myDataView As New DataView
        myDataView.Table = ds.Tables("bsktrd")
        myDataView.RowStateFilter = DataViewRowState.OriginalRows <--- key!!

        Dim c_offset As Integer
        For r As Integer = 0 To dgv.Rows.Count - 1

            myDataView.RowFilter = 'filter to find a single row in the dataview basked on r
            If myDataView(0).RowVersion <> DataRowVersion.Current Then  ' has change = original, no changes = current
                For c As Integer = 0 To dgv.Columns.Count - 2
                    If dgv(ct, r).Value <> myDataView(0).Item(c) Then
                        dgv(c, r).Style.BackColor = updated_bg
                    End If
                Next
            End If

        Next


I hacked the code a bit above but this should get you started

Author

Commented:
Cheers mate!!!Exactly what I was looking for!!!!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial