Solved

Sorting BindableList Base class

Posted on 2008-10-15
1
851 Views
Last Modified: 2013-11-07
This is not sorting correctly. Can anyone help me fix it?

Code below shows:
Business Object- clsPerson
BaseClass for Business Object Collection- clsBindingListBase
Business Object Collection.- clsPersons
PropertyComparer class- PropertyComparer

At the end of the code, the is the webform code that demonstrate's my use and there I comment what I expect and what I get.

Some of this I've pieced together from lots of reading of posts and thought I had it, but something's wrong. PS I want to use a base cass for the collection because I'll be creating lots of collections in my project and want to inherit the common functionality.

Thanks, Jeff

'''''''''''''''''''''''''''''''''
''''' Business Object Class '''''
'''''''''''''''''''''''''''''''''
Public Class clsPerson
    Private _Id As Integer
    Private _Name As String
    Public ReadOnly Property Id() As Integer
        Get
            Return _Id
        End Get
    End Property
    Public Property Name() As String
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            _Name = value
        End Set
    End Property
    Public Sub New(ByVal Name As String, ByVal Id As Integer)
        _Id = Id
        _Name = Name
    End Sub
End Class
 
''''''''''''''''''''''''''''''''''''''''''''
''''' Base class for object collection '''''
''''''''''''''''''''''''''''''''''''''''''''
Imports System.ComponentModel
Public Class clsBindingListBase(Of T)
    Inherits BindingList(Of T)
    Implements IEnumerable
 
    Private _isSorted As Boolean
 
    Protected Overloads Overrides ReadOnly Property SupportsSortingCore() As _
                                                                       Boolean
        Get
            Return True
        End Get
    End Property
    Protected Overloads Overrides Sub ApplySortCore(ByVal [property] As _ 
                      PropertyDescriptor, ByVal direction As ListSortDirection)
 
        ' Get list to sort 
        Dim items As List(Of T) = TryCast(Me.Items, List(Of T))
 
        ' Apply and set the sort, if items to sort 
        If items IsNot Nothing Then
            Dim pc As New PropertyComparer(Of T)([property], direction)
            items.Sort(pc)
            _isSorted = True
        Else
            _isSorted = False
        End If
        ' Let bound controls know they should refresh their views 
        Me.OnListChanged(New ListChangedEventArgs(ListChangedType.Reset, -1))
    End Sub
    Protected Overloads Overrides ReadOnly Property IsSortedCore() As Boolean
        Get
            Return _isSorted
        End Get
    End Property
    Protected Overloads Overrides Sub RemoveSortCore()
        _isSorted = False
    End Sub
End Class
 
''''''''''''''''''''''''''''''''''''''''''''
''''' Business Object Collection Class '''''
''''''''''''''''''''''''''''''''''''''''''''
Imports System.ComponentModel
 
Public Class clsPersons
    Inherits clsBindingListBase(Of clsPerson)
    Protected Overloads Overrides Sub ApplySortCore(ByVal [property] As _
                      PropertyDescriptor, ByVal direction As ListSortDirection)
        Dim items As List(Of clsPerson) = TryCast(Me.Items, List(Of clsPerson))
        Dim pc As New PropertyComparer(Of clsPerson)([property], direction)
        items.Sort(pc)
    End Sub
 
    Public Sub SortByName(ByVal direction As ListSortDirection)
        Dim propDescriptors As PropertyDescriptorCollection = _ 
                            TypeDescriptor.GetProperties(GetType(clsPerson))
        Me.ApplySortCore(propDescriptors("Name"), direction)
    End Sub
 
    Public Sub SortById(ByVal direction As ListSortDirection)
        Dim propDescriptors As PropertyDescriptorCollection = _ 
                            TypeDescriptor.GetProperties(GetType(clsPerson))
        Me.ApplySortCore(propDescriptors("Id"), direction)
    End Sub
End Class
 
'''''''''''''''''''''''''''
'''' Property Comparer ''''
'''''''''''''''''''''''''''
Imports System
Imports System.ComponentModel
Imports System.Collections.Generic
Imports System.Reflection
 
Public Class PropertyComparer(Of T)
    Implements System.Collections.Generic.IComparer(Of T)
    Private _property As PropertyDescriptor
    Private _direction As ListSortDirection
 
    Public Sub New(ByVal [property] As PropertyDescriptor, ByVal direction As _
                                                             ListSortDirection)
        _property = [property]
        _direction = direction
    End Sub
 
#Region "IComparer"
 
    Public Function Compare(ByVal xWord As T, ByVal yWord As T) As Integer
        ' Get property values 
        Dim xValue As Object = GetPropertyValue(xWord, _property.Name)
        Dim yValue As Object = GetPropertyValue(yWord, _property.Name)
 
        ' Determine sort order 
        If _direction = ListSortDirection.Ascending Then
            Return CompareAscending(xValue, yValue)
        Else
            Return CompareDescending(xValue, yValue)
        End If
    End Function
 
    Public Shadows Function Equals(ByVal xWord As T, ByVal yWord As T) As _
                                                                     Boolean
        Return xWord.Equals(yWord)
    End Function
 
    Public Shadows Function GetHashCode(ByVal obj As T) As Integer
        Return obj.GetHashCode()
    End Function
 
#End Region
 
    ' Compare two property values of any type 
    Private Function CompareAscending(ByVal xValue As Object, ByVal yValue As _
                                                             Object) As Integer
        Dim result As Integer
 
        ' If values implement IComparer 
        If TypeOf xValue Is IComparable Then
            result = DirectCast(xValue, IComparable).CompareTo(yValue)
            ' If values don't implement IComparer but are equivalent 
        ElseIf xValue.Equals(yValue) Then
            result = 0
        Else
            ' Values don't implement IComparer and are not equivalent, so 
            ' compare as string values 
            result = xValue.ToString().CompareTo(yValue.ToString())
        End If
 
        ' Return result 
        Return result
    End Function
 
    Private Function CompareDescending(ByVal xValue As Object, _
                                            ByVal yValue As Object) As Integer
        ' Return result adjusted for ascending or descending sort order ie 
        ' multiplied by 1 for ascending or -1 for descending 
        Return CompareAscending(xValue, yValue) * -1
    End Function
 
    Private Function GetPropertyValue(ByVal value As T, ByVal [property] As _
                                                             String) As Object
        ' Get property 
        Dim propertyInfo As PropertyInfo = _
                                      value.[GetType]().GetProperty([property])
 
        ' Return value 
        Return propertyInfo.GetValue(value, Nothing)
    End Function
 
    Public Function Compare1(ByVal x As T, ByVal y As T) As Integer _
            Implements System.Collections.Generic.IComparer(Of T).Compare
    End Function
End Class
 
'''''''''''''''''''''
''''' Form Code '''''
'''''''''''''''''''''
Dim Persons As New clsPersons
Persons.Add(New clsPerson("Jeff", "1"))
Persons.Add(New clsPerson("Lezlie", "3"))
Persons.Add(New clsPerson("Frank", "2"))
 
Response.Write("Default Order:")
For Each Person As clsPerson In Persons
    Response.Write(Person.Id & "-" & Person.Name & ", ")
Next
 
' I would expect to get below "1-Jeff, 2-Frank, 3-Lezlie"
' Instead I get below "2-Frank, 3-Lezlie, 1-Jeff"
Response.Write("Asending Order:")
Persons.SortById(ComponentModel.ListSortDirection.Ascending)
For Each Person As clsPerson In Persons
    Response.Write(Person.Id & "-" & Person.Name & ", ")
Next
 
' I would expect to get below "3-Lezlie, 2-Frank, 1-Jeff"
' Instead I get below "1-Jeff, 3-Lezlie, 2-Frank"
Response.Write("Desending Order:")
Persons.SortById(ComponentModel.ListSortDirection.Descending)
 
For Each Person As clsPerson In Persons
    Response.Write(Person.Id & "-" & Person.Name & ", ")
Next

Open in new window

0
Comment
Question by:JEFFCECCHINI
1 Comment
 

Accepted Solution

by:
JEFFCECCHINI earned 0 total points
ID: 22751164
After hours of searching I found something that worked for me...

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=20010&SiteID=1
0

Featured Post

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question