Custom Collection Question
Messages   Related Types
This message was discovered on ASPFriends.com 'aspngarchitecture' list.


CBurnet2@fnmortgage.com
I have a simple Person class that exposes FirstName, LastName, EmailAddress,
and ID properties. Now I want to build a custom People collection class. I
have read Chapter 15 in the Wrox Professional ASP.NET book which talks a lot
about working with collections and lists. So it would seem that I would
want to hold the list of Person objects in the People class using some class
that implements IEnumerable like an ArrayList or a Hashtable. The example
in the book used a Hashtable internally. The problem is how do I do
sorting? I would like to have the flexibility so that I can bind this
People object to a DataGrid or a Repeater or whatever and also sort by
FirstName or sort by LastName or sort by EmailAddress. A Hashtable doesn't
seem to support any type of sorting so it doesn't seem like I should use a
Hashtable internally in the People class. An ArrayList does support sorting
however then I can not access an item by ID like this:

myVar = objPeople.Item("1003")

I looked at the SortedList class but it seems to only sort on one item. It
seems silly to store things internally inside of the People class three
different ways because I want to sort three different ways. I am sure that
someone out there has tackled this problem before. How can I build a custom
class and a custom collection class that supports sorting on various
properties of the custom class? If possible can anyone point me to an
article, tutorial, or book that discusses this?

Thanks in advance,

Corey Burnett
Development Team Lead
First Nationwide Mortgage
301-696-4703
Click here to reveal e-mail address

Reply to this message...
 
    
Ramon Bosch

Here you have some sample code:

--> Create a VB Class Library Named "SortTest"

Person Class (paste inside a Class file named "Person.vb")
-------------------------------------------------------------
Option Strict On
Option Explicit On

Public Class Person

Public firstName As String
Public lastName As String
Public emailAddress As String

Public Sub New(ByVal firstName As String, ByVal lastName As String, ByVal
emailAddress As String)
Me.firstName = firstName
Me.lastName = lastName
Me.emailAddress = emailAddress
End Sub

End Class

People Collection (paste inside a Class file named "People.vb")
-------------------------------------------------------------

Option Strict On
Option Explicit On

Public Class People
Implements System.Collections.IEnumerable

Public Enum PeopleSortConstants
sortAscending
sordDescending
End Enum

Private _people As ArrayList = New ArrayList()
Private _currentIndex As Integer = -1

Public Sub Add(ByVal person As Person)
_people.Add(person)
End Sub

Public Sub SortByName(ByVal sort As PeopleSortConstants)
_people.Sort(New PeopleNameComparer(sort))
End Sub

Public Sub SortByEmail(ByVal sort As PeopleSortConstants)
_people.Sort(New PeopleEmailComparer(sort))
End Sub

Public Function GetEnumerator() As System.Collections.IEnumerator
Implements System.Collections.IEnumerable.GetEnumerator
Return New PeopleEnumerator(Me)
End Function

Private Class PeopleNameComparer
Implements System.Collections.IComparer

Private _sort As PeopleSortConstants

Public Sub New(ByVal sort As PeopleSortConstants)
_sort = sort
End Sub

Public Function Compare(ByVal x As Object, ByVal y As Object) As
Integer Implements System.Collections.IComparer.Compare
Dim prs1 As Person
Dim prs2 As Person

prs1 = CType(x, Person)
prs2 = CType(y, Person)

If (prs1.firstName > prs2.firstName) Then
If (_sort = PeopleSortConstants.sortAscending) Then
Return 1
Else
Return -1
End If
ElseIf (prs1.firstName = prs2.firstName) Then
Return 0
Else
If (_sort = PeopleSortConstants.sortAscending) Then
Return -1
Else
Return 1
End If
End If
End Function

End Class

Private Class PeopleEmailComparer
Implements System.Collections.IComparer

Private _sort As PeopleSortConstants

Public Sub New(ByVal sort As PeopleSortConstants)
_sort = sort
End Sub

Public Function Compare(ByVal x As Object, ByVal y As Object) As
Integer Implements System.Collections.IComparer.Compare
Dim prs1 As Person
Dim prs2 As Person

prs1 = CType(x, Person)
prs2 = CType(y, Person)

If (prs1.emailAddress > prs2.emailAddress) Then
If (_sort = PeopleSortConstants.sortAscending) Then
Return 1
Else
Return -1
End If
ElseIf (prs1.emailAddress = prs2.emailAddress) Then
Return 0
Else
If (_sort = PeopleSortConstants.sortAscending) Then
Return -1
Else
Return 1
End If
End If
End Function

End Class

Public Class PeopleEnumerator
Implements IEnumerator

Private _people As People

Public Sub New(ByVal people As People)
_people = people
Me.Reset()
End Sub

Public ReadOnly Property Current() As Object Implements
System.Collections.IEnumerator.Current
Get
Return _people._people(_people._currentIndex)
End Get
End Property

Public Function MoveNext() As Boolean Implements
System.Collections.IEnumerator.MoveNext
If (_people._currentIndex = (_people._people.Count - 1)) Then
Return False
Else
_people._currentIndex += 1
Return True
End If
End Function

Public Sub Reset() Implements System.Collections.IEnumerator.Reset
_people._currentIndex = -1
End Sub
End Class

End Class

Client code: (paste inside de Module1.vb of a Console App)
----------------------------------------------------------

Module Module1

Sub Main()

Dim prs As SortTest.Person
Dim ppl As SortTest.People = New SortTest.People()

ppl.Add(New SortTest.Person("Ramon", "Bosch", "Click here to reveal e-mail address"))
ppl.Add(New SortTest.Person("Miquel", "Bosch", "Click here to reveal e-mail address"))
ppl.Add(New SortTest.Person("Julio", "Bosch", "Click here to reveal e-mail address"))

ppl.SortByName(SortTest.People.PeopleSortConstants.sordDescending)

For Each prs In ppl
Console.WriteLine(prs.firstName)
Next
Console.ReadLine()

ppl.SortByName(SortTest.People.PeopleSortConstants.sortAscending)

For Each prs In ppl
Console.WriteLine(prs.firstName)
Next
Console.ReadLine()

ppl.SortByEmail(SortTest.People.PeopleSortConstants.sortAscending)

For Each prs In ppl
Console.WriteLine(prs.firstName)
Next
Console.ReadLine()

End Sub

End Module

--------------------------------------------------------------
End of Sample code

There are probably many other ways to do it. It's just a little bit
of code to start with. The People collection does not even have a Remove
mothod.. :-)

Ramon Bosch

[Original message clipped]

_________________________________________________________________
Chat with friends online, try MSN Messenger: http://messenger.msn.com

Reply to this message...
 
 
System.Collections.ArrayList
System.Collections.IComparer
System.Collections.IEnumerable
System.Collections.IEnumerator
System.Collections.SortedList
System.Console
System.Web.UI.WebControls.DataGrid
System.Windows.Forms.DataGrid




Ad
MBR BootFX
Best-of-breed application framework for .NET projects, developed by Matthew Baxter-Reynolds and MBR IT
 
 Copyright © Matthew Baxter-Reynolds 2001-2008. '.NET 247 Software Development Services' is a trading style of MBR IT Solutions Ltd.
Contact Us - Terms of Use - Privacy Policy - www.dotnet247.com