Solved

Sorting BindableList Base class

Posted on 2008-10-15
1
845 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

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

Welcome my friends to the second instalment and follow-up to our Minify and Concatenate Your Scripts and Stylesheets (http://www.experts-exchange.com/Programming/Languages/.NET/ASP.NET/A_4334-Minify-and-Concatenate-Your-Scripts-and-Stylesheets.html)…
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 video discusses moving either the default database or any database to a new volume.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

746 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now