sortingcomboboxtimezonecompact-frameworkopennetcf

Sorting the TimeZoneCollection list


Issue definition

I use the OpenNetCF TimeZoneCollection class to display in a ComboBox all the available time zones.

    Dim tzc As New TimeZoneCollection
    Dim TheIndex As Integer
    Dim MyTimeZoneInfo As New TimeZoneInformation

    DateTimeHelper.GetTimeZoneInformation(MyTimeZoneInfo)

    tzc.Initialize()
    For Each tzi As TimeZoneInformation In tzc
        TheIndex = ComboBox1.Items.Add(tzi)
        If tzi.StandardName = MyTimeZoneInfo.StandardName Then
            ComboBox1.SelectedIndex = TheIndex
        End If
    Next

But they are not sorted:

enter image description here

How could I sort the list?

Alphabetical order is fine, time shift order is better.

Replicate this issue on your side (need VS and a CE device)

  1. Create an empty Smart Device project (Visual Basic)
  2. Download OpenNetCF Community Edition (free)
  3. Add OpenNETCF.WindowsCE.dll as Reference (right click on the project -> Add Reference)
  4. Open Form1, add a combobox, and paste code below:

    Imports OpenNETCF.WindowsCE Public Class Form1

    Private Sub Form1_Activated(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Activated
        Dim tzc As New TimeZoneCollection
        Dim TheIndex As Integer
        Dim MyTimeZoneInfo As New TimeZoneInformation
    
        DateTimeHelper.GetTimeZoneInformation(MyTimeZoneInfo)
    
        tzc.Initialize()
        For Each tzi As TimeZoneInformation In tzc
            TheIndex = ComboBox1.Items.Add(tzi)
            If tzi.StandardName = MyTimeZoneInfo.StandardName Then
                ComboBox1.SelectedIndex = TheIndex
            End If
        Next
    End Sub
    

    End Class


Solution

  • This answer is based on @Josef's idea (written in C#), and translated to VB.

    This is the customized class:

    Public Class myTimeZoneCollection Inherits TimeZoneCollection

    Public Class myTZIComparer
        Implements IComparer
        ' return -1 for a is before b
        ' return +1 for a is after b
        ' return 0 if a is same order as b '
        Public Function Compare(ByVal a As Object, ByVal b As Object) As Integer _
            Implements IComparer.Compare
            Dim c1 As TimeZoneInformation = CType(a, TimeZoneInformation)
            Dim c2 As TimeZoneInformation = CType(b, TimeZoneInformation)
            If (c1.Bias > c2.Bias) Then
                Return -1 ' 1; //this will result in reverse offset order'
            End If
            If (c1.Bias < c2.Bias) Then
                Return 1 ' -1;'
            Else ' sort by name '
                If (c1.DisplayName < c2.DisplayName) Then
                    Return -1
                End If
                If (c1.DisplayName > c2.DisplayName) Then
                    Return 1
                Else
                    Return 0
                End If
            End If
        End Function
    End Class
    
    Public Sub MySort()
        ' Sorts the values of the ArrayList using the specific sort Comparer (by Bias)'
        Dim myComparer As IComparer = New myTZIComparer()
        Me.Sort(myComparer)
    End Sub
    

    End Class

    And this is the usage in the form

    Private Sub Form1_Activated(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Activated
        Dim tzc As New myTimeZoneCollection ' this is the customized class
        Dim TheIndex As Integer ' this index is used to select the activated time zone of the system
        Dim MyTimeZoneInfo As New TimeZoneInformation
    
        DateTimeHelper.GetTimeZoneInformation(MyTimeZoneInfo)
    
        tzc.Initialize()
        tzc.MySort()
        ' Clear the item list otherwise it is increased at each Activated event.. '
        ComboBox1.Items.Clear()
        For Each tzi As TimeZoneInformation In tzc
            TheIndex = ComboBox1.Items.Add(tzi)
            If tzi.StandardName = MyTimeZoneInfo.StandardName Then
                ComboBox1.SelectedIndex = TheIndex
            End If
        Next
    End Sub
    

    I validated this code on a device, it works fine.