none
iBindingList issue with sort to datagridview RRS feed

  • Question

  • My fellow programmers:

    I am getting this error

    I am using linq to build the table to bind to the datagridview

     Dim logEntries = (From le In coidb.COI_Logs
                                      Where le.LogDate < Now And le.LogDate > DateAdd(DateInterval.Day, -90, Now())
                                      Select New COILogFile With {
                                                                  .LogID = le.LogID,
                                                                  .ProcessType = le.ProcessType,
                                                                  .LogDate = le.LogDate,
                                                                  .LogNote = le.LogNote,
                                                                  .LoggedBy = le.LoggedBy}).ToList
                    dgvLogs.DataSource = logEntries
                    dgvLogs.Columns(0).Visible = False

    What might I be missing here as I want to sort when the column header is clicked and this is the code for that

    Dim newColumn As DataGridViewColumn =
                dgvLogs.Columns(e.ColumnIndex)
            Dim oldColumn As DataGridViewColumn = dgvLogs.SortedColumn
            Dim direction As ListSortDirection
    
            If oldColumn IsNot Nothing Then
                'sort the same column again, reversing the sort order
                If oldColumn Is newColumn AndAlso dgvLogs.SortOrder = SortOrder.Ascending Then
                    direction = ListSortDirection.Descending
                Else
                    direction = ListSortDirection.Ascending
                    oldColumn.HeaderCell.SortGlyphDirection = SortOrder.None
                End If
            Else
                direction = ListSortDirection.Ascending
            End If
    
            dgvLogs.Sort(newColumn, direction)
    
            If direction = ListSortDirection.Ascending Then
                newColumn.HeaderCell.SortGlyphDirection = SortOrder.Ascending
            Else
                newColumn.HeaderCell.SortGlyphDirection = SortOrder.Descending
            End If
        End Sub

    Thanks


    Brad Allison

    Wednesday, October 9, 2019 6:47 PM

Answers

  • Tried it and yes it fills the datagrid, but when I try to sort I get this error: 'DataGridView control cannot be sorted if it is bound to an IBindingList that does not support sorting'.


    Brad Allison

    Then implement the following sortable BindingList. The custom BindingList is in a class project which can be used in your project and to try it out there id a Windows Form project.

    https://code.msdn.microsoft.com/windowsdesktop/Generic-sortable-binding-47cac3cc


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Thursday, October 10, 2019 12:29 PM
    Moderator

All replies

  • Try this

    dgvLogs.DataSource = New BindingSource(logEntries, Nothing)


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Wednesday, October 9, 2019 6:52 PM
    Moderator
  • Just checking in to see if what I recommended has been tried yet?

    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Wednesday, October 9, 2019 8:59 PM
    Moderator
  • Nope, not yet as I was "offline" most of yesterday afternoon, and I just got in this morning, but I will try it soon and let you know.

    Brad Allison

    Thursday, October 10, 2019 10:23 AM
  • Tried it and yes it fills the datagrid, but when I try to sort I get this error: 'DataGridView control cannot be sorted if it is bound to an IBindingList that does not support sorting'.


    Brad Allison

    Thursday, October 10, 2019 11:05 AM
  • Tried it and yes it fills the datagrid, but when I try to sort I get this error: 'DataGridView control cannot be sorted if it is bound to an IBindingList that does not support sorting'.


    Brad Allison

    Then implement the following sortable BindingList. The custom BindingList is in a class project which can be used in your project and to try it out there id a Windows Form project.

    https://code.msdn.microsoft.com/windowsdesktop/Generic-sortable-binding-47cac3cc


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Thursday, October 10, 2019 12:29 PM
    Moderator
  • I changed the linq query to be "Dim logEntries As IQueryable(Of COILogFile)" and it works.  Thanks for your help and direction

    Brad Allison

    Thursday, October 10, 2019 12:32 PM
  • Here is another option

    Dim myView = New BindingListView(Of COILogFile)(logEntries)

    Then

    dgvLogs.DataSource = myView

    Custom component

    Imports System.ComponentModel
    ''' <summary>
    ''' Provides a generic collection that supports data binding and additionally supports sorting.
    ''' See http://msdn.microsoft.com/en-us/library/ms993236.aspx
    ''' If the elements are IComparable it uses that; otherwise compares the ToString()
    ''' </summary>
    ''' <typeparam name="T">The type of elements in the list.</typeparam>
    Public Class SortableBindingList(Of T As Class)
        Inherits BindingList(Of T)
    
        Private _isSorted As Boolean
        Private _sortDirection As ListSortDirection = ListSortDirection.Ascending
        Private _sortProperty As PropertyDescriptor
    
        Public Sub New()
        End Sub
    
        Public Sub New(ByVal list As IList(Of T))
            MyBase.New(list)
        End Sub
    
        ''' <summary>
        ''' Gets a value indicating whether the list supports sorting.
        ''' </summary>
        Protected Overrides ReadOnly Property SupportsSortingCore() As Boolean
            Get
                Return True
            End Get
        End Property
    
        ''' <summary>
        ''' Gets a value indicating whether the list is sorted.
        ''' </summary>
        Protected Overrides ReadOnly Property IsSortedCore() As Boolean
            Get
                Return _isSorted
            End Get
        End Property
    
        ''' <summary>
        ''' Gets the direction the list is sorted.
        ''' </summary>
        Protected Overrides ReadOnly Property SortDirectionCore() As ListSortDirection
            Get
                Return _sortDirection
            End Get
        End Property
    
        ''' <summary>
        ''' Gets the property descriptor that is used for sorting the list if sorting is implemented in a derived class; otherwise, returns null
        ''' </summary>
        Protected Overrides ReadOnly Property SortPropertyCore() As PropertyDescriptor
            Get
                Return _sortProperty
            End Get
        End Property
    
        ''' <summary>
        ''' Removes any sort applied with ApplySortCore if sorting is implemented
        ''' </summary>
        Protected Overrides Sub RemoveSortCore()
            _sortDirection = ListSortDirection.Ascending
            _sortProperty = Nothing
            _isSorted = False 'thanks Luca
        End Sub
    
        ''' <summary>
        ''' Sorts the items if overridden in a derived class
        ''' </summary>
        ''' <param name="prop"></param>
        ''' <param name="direction"></param>
        Protected Overrides Sub ApplySortCore(ByVal prop As PropertyDescriptor, ByVal direction As ListSortDirection)
            _sortProperty = prop
            _sortDirection = direction
    
            Dim list As List(Of T) = TryCast(Items, List(Of T))
            If list Is Nothing Then
                Return
            End If
    
            list.Sort(AddressOf Compare)
    
            _isSorted = True
            'fire an event that the list has been changed.
            OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1))
        End Sub
    
        Private Function Compare(ByVal lhs As T, ByVal rhs As T) As Integer
            Dim result = OnComparison(lhs, rhs)
            'invert if descending
            If _sortDirection = ListSortDirection.Descending Then
                result = -result
            End If
            Return result
        End Function
    
        Private Function OnComparison(ByVal lhs As T, ByVal rhs As T) As Integer
            Dim lhsValue As Object = If(lhs Is Nothing, Nothing, _sortProperty.GetValue(lhs))
            Dim rhsValue As Object = If(rhs Is Nothing, Nothing, _sortProperty.GetValue(rhs))
            If lhsValue Is Nothing Then
                Return If(rhsValue Is Nothing, 0, -1) 'nulls are equal
            End If
            If rhsValue Is Nothing Then
                Return 1 'first has value, second doesn't
            End If
            If TypeOf lhsValue Is IComparable Then
                Return CType(lhsValue, IComparable).CompareTo(rhsValue)
            End If
            If lhsValue.Equals(rhsValue) Then
                Return 0 'both are the same
            End If
            'not comparable, compare ToString
            Return lhsValue.ToString().CompareTo(rhsValue.ToString())
        End Function
    End Class



    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange


    Thursday, October 10, 2019 12:39 PM
    Moderator