This is a migrated thread and some comments may be shown as answers.

Strategy for sorting GridViewComboBoxColumn by the DisplayMemberPath

8 Answers 363 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Duncan
Top achievements
Rank 1
Duncan asked on 26 Oct 2012, 05:41 PM
I understand from scouring this forum that the GridViewComboBoxColumn does not sort by the DisplayMemberPath, it sorts by the DataMemberBinding which is essentially a property of the item the row is bound to.  You can set the SortMemberPath but again that is just a different property of the item the row is bound to, not a property of the GridViewComboBoxColumn ItemsSource.  With that said, the filter control displays the DisplayMemberPath and even sorts the items properly.

I'm looking for a way to get the GridViewComboBoxColumn to sort on the DisplayMemberPath, but I do not want to code this for every single grid with custom sorting or every single GridViewComboBoxColumn I add to our application.  There are a number of developers on this project and undoubtedly one will forget to do it, and this is not really maintainable either.  

Ideally I could have my own SortableGridViewComboBoxColumn I could use that inherited from the GridViewComboBoxColumn but I have not had much luck going down this road so far.  Is there any advice you can give or samples I can look at?  I've been through almost everything on this forum already.

Thanks.


8 Answers, 1 is accepted

Sort by
0
Dimitrina
Telerik team
answered on 29 Oct 2012, 08:06 AM
Hello,

Actually such a feature has already been implemented. You may find additional information in this forum thread. Please let me know in case you have any further questions.

All the best,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Duncan
Top achievements
Rank 1
answered on 29 Oct 2012, 03:20 PM
Unfortunately that does not solve the sorting problem.  I do not have a problem with the filtering control, I have a problem with the sorting of the GridViewComboBoxColumn.  The default sort works off of the DataMemberBinding unless you set the SortMemberPath, but the SortMemberPath is simply another property on the object the row is bound to.  In your example the ViewModel is adding a new property called SortID and setting that for every object.  

What happens if I add a new object to the collection?  Now I have to loop through the entire collection and set the "SortID" property for every combo box column in the grid.  Not elegant.

I am looking for a way to get the control to sort by DisplayMemberPath so I don't need to create many many seperate properties for the grids in our application.  
0
Dimitrina
Telerik team
answered on 30 Oct 2012, 12:34 PM
Hi,

Indeed additional setting of the SortMemberPath will be needed. In order to avoid this, you could handle the Sorting event of the RadGridView and apply your custom sorting which sorts based on the DisplayMemberPath. You can check the CustomSorting WPF Demo and our online documentation for an example.

Greetings,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Duncan
Top achievements
Rank 1
answered on 30 Oct 2012, 03:26 PM
As I explained in the first post I would rather not use custom sorting because I have to implement that on every GridViewComboBoxColumn in every grid inside the application, some of these columns are built dynamically as well which adds another layer of complexity.  I am looking for something generic that I can reuse over and over.

Is there no way to inherit from the GridViewComboBoxColumn and write some generic code to sort?  That way we simply use this new column and the application will behave as all users would expect it to behave.
0
Dimitrina
Telerik team
answered on 30 Oct 2012, 03:34 PM
Hi,

Unfortunately this is what we can suggest regarding Sorting of this column. Inheriting it will not help as the sorting logic is in the Data Engine, it is not in the column.  

Kind regards,
Didie
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Anton
Top achievements
Rank 2
answered on 10 Nov 2015, 12:52 PM
Hi Duncan. Did you solve your problem? I have the same and don't know how to implement it via custom combobox column.
0
Duncan
Top achievements
Rank 1
answered on 10 Nov 2015, 07:03 PM

No, I never got it working.  I did try using a custom column but that had its own challenges.  What I typically do now is use a regular data column and change the cell edit template to a combo box.

0
Patrick
Top achievements
Rank 1
answered on 23 Apr 2019, 06:40 PM

I found out a solution, maybe it could be simplier, but for me it is good enough.

First you have to set ".IsCustomSortingEnabled = True" on the GridViewComboBoxColumn.

Then in the sorting handler:

Private Sub Datagr_Sorting(sender As Object, e As GridViewSortingEventArgs) Handles Datagr.Sorting
                Dim CB = TryCast(e.Column, GridViewComboBoxColumn)
                If Not CB Is Nothing Then
                    If e.Column.IsCustomSortingEnabled Then
                        Dim cbis = TryCast(CB.ItemsSource, DataView)
                        If Not cbis Is Nothing Then
                            Datagr.SortDescriptors.Clear()
                            If e.OldSortingState = SortingState.None Or e.OldSortingState = SortingState.Descending Then
                                e.NewSortingState = SortingState.Ascending
                            ElseIf e.OldSortingState = SortingState.Ascending Then
                                e.NewSortingState = SortingState.Descending
                                'Else
                                '    'If the sorting state is descending, apply default sorting to the items.
                                '    e.NewSortingState = SortingState.None
                            End If
                            ' create new DV
                            Dim dgvDV = DGVNaturalColumnSort(CB.SelectedValueMemberPath, e.NewSortingState, CB.DisplayMemberPath, cbis)
                            'Set the sorted collection as source of the RadGridView
                            e.DataControl.ItemsSource = dgvDV
                            e.Cancel = True
                            Exit Sub
                        End If
                    End If
                End If
                    'All others
                    If e.NewSortingState = SortingState.None Then
                    e.NewSortingState = SortingState.Ascending
                End If
End sub

 

and

Private Function DGVNaturalColumnSort(colName As String, sortt As SortingState, sortName As String, dbis As DataView) As DataView
        Dim NComparer As New NaturalStringComparer(sortt, colName, sortName, dbis)
        Try
            Dim tempDT = datatable.DefaultView.Table.AsEnumerable().OrderBy(Function(s) s.Field(Of Object)(colName), NComparer).CopyToDataTable
            Return New DataView(tempDT)
        Catch ex As Exception
            Return Nothing
        End Try
    End Function

 

and

Public Class NaturalStringComparer
        Implements IComparer(Of String)
        Dim mysortflipper As SortingState
        Dim mycolName As String
        Dim mysortName As String
        Dim dict As New Dictionary(Of Integer, String)()
 
        Public Sub New()
        End Sub
 
        Public Sub New(sort As SortingState, colName As String, sortName As String, dbis As DataView)
            mysortflipper = sort
            mycolName = colName
            mysortName = sortName
            For Each a In dbis.Table.AsEnumerable
                dict.Add(a.Field(Of Object)(colName), a.Field(Of Object)(sortName))
            Next
        End Sub
 
        Public Function Compare(x As String, y As String) As Integer _
            Implements IComparer(Of String).Compare
            ' convert DBNull to empty string
            Dim x1 = If(String.IsNullOrEmpty(x), String.Empty, dict(x))
            Dim y1 = If(String.IsNullOrEmpty(y), String.Empty, dict(y))
 
            'String Compare
            Select Case mysortflipper
                Case SortingState.Ascending
                    Return String.Compare(x1, y1)
                Case Else
                    Return String.Compare(y1, x1)
            End Select
        End Function
    End Class

 

Maybe you will find an eleganter solution.

Regards,

Patrick

Tags
GridView
Asked by
Duncan
Top achievements
Rank 1
Answers by
Dimitrina
Telerik team
Duncan
Top achievements
Rank 1
Anton
Top achievements
Rank 2
Patrick
Top achievements
Rank 1
Share this question
or