Solved

Sorting

Posted on 2004-03-29
6
802 Views
Last Modified: 2012-05-04
I have a class that inherits from collection base and I want to implement a custom comparing mechanism with the sort routine.

So in my collection I want to have something like

Sort(columnIndex as int32, sortOrder as ComponentModel.ListSortOrder)

Now I know that I can create a class that implements an IComparer interface and pass this class into the Sort method of the InnerList property of the CollectionBase class and have tried this, but it is not ever calling my comparing code.

Here is what I have:

Public Class NodeCollection
Inherits CollectionBase

        Public Sub Sort(ByVal columnIndex As Int32, ByVal sortOrder As System.ComponentModel.ListSortDirection)
            Dim sorter As New Node.AdvancedSort
            sorter.ColumnIndex = columnIndex
            sorter.ListSortOrder = sortOrder
            MyBase.InnerList.Sort(sorter)
        End Sub

End Class

Public Class Node

    Public Class AdvancedSort
            Implements System.Collections.IComparer

            Private _ColumnIndex As Int32
            Private _ListSortOrder As System.ComponentModel.ListSortDirection

            Public Property ColumnIndex() As Int32
                Get
                    Return _ColumnIndex
                End Get
                Set(ByVal Value As Int32)
                    _ColumnIndex = Value
                End Set
            End Property

            Public Property ListSortOrder() As System.ComponentModel.ListSortDirection
                Get
                    Return _ListSortOrder
                End Get
                Set(ByVal Value As System.ComponentModel.ListSortDirection)
                    _ListSortOrder = Value
                End Set
            End Property

            Public Function Compare(ByVal x As Object, ByVal y As Object) As Int32 Implements System.Collections.IComparer.Compare
               'My logic to sort is here
            End Sub
   End Class
End Class

Nowif I step through the code in the Sort method and put a breakpoint or any code (like throwing an exception) in the Compare method that code is never executed and my collection is not being sorted
0
Comment
Question by:pcavacas
  • 3
6 Comments
 
LVL 12

Expert Comment

by:farsight
ID: 10710455
I'm not sure why you're having a problem.  I had no problem.  This code works fine for me. (Win2K, VS.NET 2003)

I just started with your code, added several things:
  TrySortCollection.Test -- to setup a list of nodes and call sorts.  (I'm actually testing by eyeballing the output.)
  TrySortCollection -- utils for random numbers
  NodeCollection.Add
  Node.column1
  Node.column2
  Node constructor New
  Node.ToString
  AdvancedSort.Compare -- added an implementation for the existing function.

Try it!   How's it different from what you have?
If my code doesn't work on your machine, we have a real mystery brewing here!

[VB.NET]
Option Explicit On
Option Strict On

Public Class TrySortCollection
    Private Shared r As New System.Random

    Public Shared Sub Test()
        Dim size As Integer = 4
        Dim nc As New NodeCollection
        For i As Integer = 1 To size
            nc.Add(New Node(GetRnd(), GetRnd()))
        Next

        ' Sort by 1st column, and show.
        nc.Sort(1, System.ComponentModel.ListSortDirection.Ascending)
        For Each n As Node In nc
            Debug.WriteLine("1 -- " & n.ToString())
        Next

        ' Sort by 2nd column, and show.
        nc.Sort(2, System.ComponentModel.ListSortDirection.Ascending)
        For Each n As Node In nc
            Debug.WriteLine("2 -- " & n.ToString())
        Next
    End Sub

    Private Shared Function GetRnd() As Integer
        Return r.Next(0, 100)
    End Function
End Class

Public Class NodeCollection
    Inherits CollectionBase

    Public Sub Sort(ByVal columnIndex As Int32, ByVal sortOrder As System.ComponentModel.ListSortDirection)
        Dim sorter As New Node.AdvancedSort
        sorter.ColumnIndex = columnIndex
        sorter.ListSortOrder = sortOrder
        MyBase.InnerList.Sort(sorter)
    End Sub

    Public Sub Add(ByVal node As Node)
        MyBase.InnerList.Add(node)
    End Sub

End Class

Public Class Node
    Public ReadOnly column1 As Integer
    Public ReadOnly column2 As Integer

    Public Sub New(ByVal col1 As Integer, ByVal col2 As Integer)
        column1 = col1
        column2 = col2
    End Sub

    Public Overrides Function ToString() As String
        Return String.Format("Node({0},{1})", column1, column2)
    End Function

    Public Class AdvancedSort
        Implements System.Collections.IComparer

        Private _ColumnIndex As Int32
        Private _ListSortOrder As System.ComponentModel.ListSortDirection

        Public Property ColumnIndex() As Int32
            Get
                Return _ColumnIndex
            End Get
            Set(ByVal Value As Int32)
                _ColumnIndex = Value
            End Set
        End Property

        Public Property ListSortOrder() As System.ComponentModel.ListSortDirection
            Get
                Return _ListSortOrder
            End Get
            Set(ByVal Value As System.ComponentModel.ListSortDirection)
                _ListSortOrder = Value
            End Set
        End Property

        Public Function Compare(ByVal x As Object, ByVal y As Object) As Int32 Implements System.Collections.IComparer.Compare
            'My logic to sort is here
            Dim result As Integer

            Dim xNode As Node = DirectCast(x, Node)
            Dim yNode As Node = DirectCast(y, Node)

            Select Case _ColumnIndex
                Case 1
                    If xNode.column1 > yNode.column1 Then
                        result = 1
                    ElseIf xNode.column1 < yNode.column1 Then
                        result = -1
                    Else
                        result = 0
                    End If

                Case 2
                    If xNode.column2 > yNode.column2 Then
                        result = 1
                    ElseIf xNode.column2 < yNode.column2 Then
                        result = -1
                    Else
                        result = 0
                    End If

                Case Else
                    Throw New ApplicationException("AdvancedSort is improperly configured: ColumnIndex.")
            End Select
            If _ListSortOrder = System.ComponentModel.ListSortDirection.Descending Then
                result = -result
            End If
            Return result
        End Function
    End Class
End Class
0
 
LVL 12

Expert Comment

by:farsight
ID: 10710461
pcavacas,
It sounds like your already familiar with this stuff, but for a quick review, or for other readers:

HOW TO: Use the IComparable and the IComparer Interfaces in Visual Basic .NET
http://support.microsoft.com/default.aspx?scid=kb;EN-US;q321292
0
 
LVL 2

Author Comment

by:pcavacas
ID: 10713715
  Your example worked.  Also if I copy out the relevant portions code from my project into another project I can get it to work there as well.  But for some reason when it is in my project it is not working.  Stepping through the code I walk right through the Sort method where it creates an instance of AdvancedSort class and calls the sort on the Innerlist.  It just never goes into the Cmopare method.
0
 
LVL 12

Accepted Solution

by:
farsight earned 500 total points
ID: 10717948
Given that, I'd assume the project is somehow corrupted.

Given that your project's named:   Xxxx
Rename your project to   OldXxxx
Remove it from your solution ( Don't delete it! )
Create a new project Xxxx in your solution.
Create new files in the new project as needed.
Copy-and-paste all your code from the old project to the new project.

I don't have any better ideas than that.   I hope it works.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
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.
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

705 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

19 Experts available now in Live!

Get 1:1 Help Now