I would subclass the TimeZoneCollection and add a Sort method as you alreday found but more or less implement by hand. I was not bale to verify the following as I do not have a compact framework here:
In the subclassed TimeZoneCollection add a sort method and a IComparable class. Within that class you can define whatever sort order you wich (by names, by GMT-offset...):
...
public class myTimeZoneCollection:TimeZoneCollection{
...
public class myTZIComparer : IComparer {
// return -1 for a is before b
// return +1 for a is after b
// return 0 if a is same order as b
int IComparer.Compare( Object a, Object b ) {
{
TZData c1=(TZData)a;
TZData c2=(TZData)b;
if (c1.GMTOffset > c2.GMTOffset)
return -1;//1; //this will result in reverse offset order
if (c1.GMTOffset < c2.GMTOffset)
return 1;//-1;
else
return 0;
}
}
...
public void sort(){
// Sorts the values of the ArrayList using the reverse case-insensitive comparer.
IComparer myComparer = new myTZIComparer();
this.Sort( myComparer );
}
...
}
And yes, I am sorry, this is in C# but must be do also in VB.
And, use the sorted my TimeZoneCollection to add the elements to the combobox. There is no additional work needed to get the list into the combobox in a custom sort order. Just do foreach and add.
Here is the promised full VB solution with the OpenNetCF fix:
myTimeZoneCollection.vb:
Option Strict On
Option Explicit On
Imports OpenNETCF.WindowsCE
Public Class myTimeZoneCollection
Inherits TimeZoneCollection
Dim tzc As New TimeZoneCollection
Public Sub New()
End Sub
Overloads Function Initialize() As TimeZoneCollection
tzc.Initialize()
Dim myComparer = New myTZIComparer()
tzc.Sort(myComparer)
Return tzc
End Function
Shared Function getOffsetFromDisplayName(ByVal tzi As TimeZoneInformation) As Integer
' known forms
' GMT = no offset
' GMT+6 = 6 hours offset
' GMT-12 = -6 hours offset
' GMT+4:30 = 4 hours and 30 minutes offset
' GMT-4:30 = - 4 hours and 30 minutes offset
' all these end with a space! followed by the name of the time zone
'System.Diagnostics.Debug.WriteLine("getOffsetFromDisplayName: tzi=" & tzi.ToString())
'extract offset
If (tzi.DisplayName = "GMT") Then
Return 0
End If
Dim subStr As String
subStr = tzi.DisplayName.Substring(0, tzi.DisplayName.IndexOf(" "c)) 'GMT+x or GMT-x or GMT+x:yy or GMT-x:yy
If (subStr = "GMT") Then
Return 0
End If
subStr = subStr.Substring(3) 'cut GMT from begin
'now check if this is with a minute value
Dim hoursOffset, minutesOffset, idxOfColon, idxM As Integer : idxOfColon = 0 : idxM = 0
idxOfColon = subStr.IndexOf(":"c)
If (idxOfColon = -1) Then 'no : found
hoursOffset = System.Int32.Parse(subStr)
minutesOffset = hoursOffset * 60
Else
Dim sH, sM As String
sH = subStr.Substring(0, subStr.Length - idxOfColon - 1)
sM = subStr.Substring(idxOfColon + 1)
hoursOffset = System.Int32.Parse(sH)
minutesOffset = System.Int32.Parse(sM)
If (hoursOffset > 0) Then
minutesOffset = minutesOffset + hoursOffset * 60
Else
minutesOffset = hoursOffset * 60 - minutesOffset
End If
End If
Return minutesOffset
End Function
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)
Dim offset1, offset2 As Integer
offset1 = getOffsetFromDisplayName(c1)
offset2 = getOffsetFromDisplayName(c2)
If (offset1 > offset2) Then
Return -1 '//1; //this will result in reverse offset order
ElseIf (offset1 < offset2) Then
Return 1 '//-1;
Else 'offsets equal, sort by name
If (c1.DisplayName < c2.DisplayName) Then
Return -1
ElseIf (c1.DisplayName > c2.DisplayName) Then
Return 1
Else
Return 0
End If
End If
End Function
End Class
End Class
By changing or adding another myTZIComparer you can define the order of the entries.
The OpenNetCF code is wrong for the new timezone names
' GMT+4:30 = 4 hours and 30 minutes offset
' GMT-4:30 = - 4 hours and 30 minutes offset
as it does only look for full hour offsets. So I needed to develop a new 'parser' to get the bias data.
In your code with the listbox:
Public Sub fillList()
ComboBox1.Items.Clear()
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
The above fills the list in the order the items are.
Public Sub fillListGMT()
ComboBox1.Items.Clear()
Dim tzc As New myTimeZoneCollection 'subclassed one
Dim TheIndex As Integer
Dim MyTimeZoneInfo As New TimeZoneInformation
DateTimeHelper.GetTimeZoneInformation(MyTimeZoneInfo)
Dim tzc1 As New TimeZoneCollection
tzc1.Clear()
tzc1 = tzc.Initialize()
For Each tzi As TimeZoneInformation In tzc1
TheIndex = ComboBox1.Items.Add(tzi)
If tzi.StandardName = MyTimeZoneInfo.StandardName Then
ComboBox1.SelectedIndex = TheIndex
End If
Next
End Sub
The code above fills the list ordered by GMT offset.