toddhd
asked on
Sorting an ICollection on more than one field
I have a custom Collection called Subscriptions. It is basically an ArrayList of objects of type Subscription.
SubScription is a class with 3 fields - Group, Title and URL.
When I load the subscriptions, they will be represented in a TreeView - the Title of each Subscription is displayed.
Subscriptions that have the same Group type should show in a Folder of the same name in the TreeView.
So when I load the treeview, I want to display the Folders (Groups) in alphabetical order, and the Subscriptions (Titles) in Alphabetical order.
So - it should be sorted by Group, then by Title.
Here is the code for the Subscriptions Class, and the accompanying IComparers for the sorts:
-------------------------- ---------- ---------- -------
Public Class Subscriptions
Implements ICollection
Private al As ArrayList = New ArrayList
Default Public Overloads ReadOnly _
Property Item(ByVal index As Integer) As SubScription
Get
Return CType(al(index), Subscription)
End Get
End Property
Public Sub CopyTo(ByVal a As Array, ByVal index As Integer) Implements ICollection.CopyTo
al.CopyTo(a, index)
End Sub
Public ReadOnly Property Count() As Integer Implements ICollection.Count
Get
Count = al.Count
End Get
End Property
Public ReadOnly Property SyncRoot() As Object Implements ICollection.SyncRoot
Get
Return Me
End Get
End Property
Public ReadOnly Property IsSynchronized() As Boolean Implements ICollection.IsSynchronized
Get
Return False
End Get
End Property
Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return al.GetEnumerator()
End Function
Public Function Add(ByVal newSubscription As SubScription) As Integer
al.Add(newSubscription)
Return al.Count
End Function
Public Function Sort()
Dim GroupSorter As IComparer = New GroupComparer
al.Sort(GroupSorter)
End Function
End Class
Public Class GroupComparer
Implements IComparer
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.ICompar er.Compare
Dim s1 As String = LCase(CType(x, Subscription).Group)
Dim s2 As String = LCase(CType(y, Subscription).Group)
Return s1.CompareTo(s2)
End Function
End Class
Public Class TitleComparer
Implements IComparer
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.ICompar er.Compare
Dim s1 As String = LCase(CType(x, Subscription).Title)
Dim s2 As String = LCase(CType(y, Subscription).Title)
Return s1.CompareTo(s2)
End Function
End Class
-------------------------- ---------- ---
Ok, if you look at the Sort() function, it is sorting by Group. If I was simply to sort again by Title, it would sort everything, and lose the group sort.
SO HERE IS THE QUESTION - How do I write this, so that when I call Sort() it sorts everything by Group and Title?
Thanks
SubScription is a class with 3 fields - Group, Title and URL.
When I load the subscriptions, they will be represented in a TreeView - the Title of each Subscription is displayed.
Subscriptions that have the same Group type should show in a Folder of the same name in the TreeView.
So when I load the treeview, I want to display the Folders (Groups) in alphabetical order, and the Subscriptions (Titles) in Alphabetical order.
So - it should be sorted by Group, then by Title.
Here is the code for the Subscriptions Class, and the accompanying IComparers for the sorts:
--------------------------
Public Class Subscriptions
Implements ICollection
Private al As ArrayList = New ArrayList
Default Public Overloads ReadOnly _
Property Item(ByVal index As Integer) As SubScription
Get
Return CType(al(index), Subscription)
End Get
End Property
Public Sub CopyTo(ByVal a As Array, ByVal index As Integer) Implements ICollection.CopyTo
al.CopyTo(a, index)
End Sub
Public ReadOnly Property Count() As Integer Implements ICollection.Count
Get
Count = al.Count
End Get
End Property
Public ReadOnly Property SyncRoot() As Object Implements ICollection.SyncRoot
Get
Return Me
End Get
End Property
Public ReadOnly Property IsSynchronized() As Boolean Implements ICollection.IsSynchronized
Get
Return False
End Get
End Property
Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return al.GetEnumerator()
End Function
Public Function Add(ByVal newSubscription As SubScription) As Integer
al.Add(newSubscription)
Return al.Count
End Function
Public Function Sort()
Dim GroupSorter As IComparer = New GroupComparer
al.Sort(GroupSorter)
End Function
End Class
Public Class GroupComparer
Implements IComparer
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.ICompar
Dim s1 As String = LCase(CType(x, Subscription).Group)
Dim s2 As String = LCase(CType(y, Subscription).Group)
Return s1.CompareTo(s2)
End Function
End Class
Public Class TitleComparer
Implements IComparer
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.ICompar
Dim s1 As String = LCase(CType(x, Subscription).Title)
Dim s2 As String = LCase(CType(y, Subscription).Title)
Return s1.CompareTo(s2)
End Function
End Class
--------------------------
Ok, if you look at the Sort() function, it is sorting by Group. If I was simply to sort again by Title, it would sort everything, and lose the group sort.
SO HERE IS THE QUESTION - How do I write this, so that when I call Sort() it sorts everything by Group and Title?
Thanks
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.