none
How to sort Combobox items?

    Question

  • I have stored 10 integer items in combo box and also has set the property SORTED =TRUE in the property window.

    And during run time when I view the items in combo box they are listed as

    1

    10

    2

    3

    4

    5

    6

    7

    8

    9

    So the 10th value is listed at 2nd position.

    Can anyone please tell me how to sort this problem?

    Thank you in advance

    Tuesday, March 21, 2017 7:05 PM

All replies

  • Tabzee,

    The problem is that it's inferring the numbers as strings and thus what you see is a string sort.

    Instead, use real numbers, sort them (as numbers) and then add each string equivalent of those numbers and they'll be in the right order:

    Option Strict On Option Explicit On Option Infer Off Public Class Form1 Private Sub Form1_Load(sender As System.Object, _ e As System.EventArgs) _ Handles MyBase.Load Dim numbers As IEnumerable(Of Integer) = Enumerable.Range(1, 10) Using combo As New ComboBox For Each i As Integer In numbers combo.Items.Add(i.ToString) Next End Using Stop End Sub End Class


    In that one, I don't have to sort them, but hopefully you get the idea.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Tuesday, March 21, 2017 7:22 PM
  • Thank you for your response.

    I guess,i did not clearly stated my problem.

    I have two combo box in project. And in run time the values between them keeps on interchanging (Both contains only integer values). For example first combo box has numbers 1 to 15, and then value 1  goes to second combo box, followed by 15,4,5 and 3(and these items will be removed from first combo box). 

    Now in second combo box the items will be stored as

    1

    15

    3

    4

    5

    I want these numbers in second combo box to sort those elements and display in ascending order(example 1,3,4,5,15).

    And also number of Items supplied to first combo box depends on the user. It may be 50 or 100.

    Please help me to sort the values of combo box(I have set the property SORTED =TRUE)

    Thank you in advance

    Tuesday, March 21, 2017 8:06 PM
  • Thank you for your response.

    I guess,i did not clearly stated my problem.

    I have two combo box in project. And in run time the values between them keeps on interchanging (Both contains only integer values). For example first combo box has numbers 1 to 15, and then value 1  goes to second combo box, followed by 15,4,5 and 3(and these items will be removed from first combo box). 

    Now in second combo box the items will be stored as

    1

    15

    3

    4

    5

    I want these numbers in second combo box to sort those elements and display in ascending order(example 1,3,4,5,15).

    And also number of Items supplied to first combo box depends on the user. It may be 50 or 100.

    Please help me to sort the values of combo box(I have set the property SORTED =TRUE)

    Thank you in advance

    That's nothing like what you asked, but -- the sort order depends on the type.

    If it's a string, you'll get a string order, so to do what you want, make sure you're dealing with numbers, then show the numbers as strings.

    If you do it that way then turn .Sorted off so there's no confusion.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Tuesday, March 21, 2017 8:13 PM
  • Do you have Option Strict set to On?

    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Tuesday, March 21, 2017 8:13 PM
  • You could use the following as each item is seen as a object.

    Public Class Form1
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim results As IOrderedEnumerable(Of Integer) =
                (
                    From item In ComboBox1.Items
                    Select CInt(item)).ToList.OrderBy(Function(item) item
                )
            ComboBox1.Items.Clear()
            For Each item In results
                ComboBox1.Items.Add(item)
            Next
        End Sub
    End Class
    


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Tuesday, March 21, 2017 9:09 PM
    Moderator
  • The problem you are having is that the internal IComparer of the ComboBox is a text comparer.

    It compares the items.ToString.

    Now, what you want is an integer comparer.

    A problem is that the comparer is a private field in the itemCollection, which is also a private field

    The only way to have it like you want it to work is to create a compatible integer comparer and to inject that comparer into the instance of the Combobox

    .

    REMEMBER, .. once the comparer is replaced by a Integer comparer, the combobox will only sort integers. Of course, you can implement the comparer as you want it. A text and integer comparer if you want

    .

    .

    Option Strict On
    
    Public Class Form1
    
        Private CB As New ComboBox With {.Parent = Me, .Sorted = True}
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            InjectComparerInCombobox(CB, New ItemComparer(CB))
        End Sub
    
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            CB.Items.AddRange(New ArrayList From {1, 2, 3, 4, 5, 6, 12, 7, 8, 25, 10, 11, 22, 33}.ToArray)
        End Sub
    
    
        Private Sub InjectComparerInCombobox(CB As ComboBox, Comparer As IComparer)
            'An item need to be added and removed to init the object collection
            CB.Items.Add(1)
            CB.Items.Clear()
    
            'Get the value in the itemCollection field
            Dim T As Type = CB.GetType
            Dim IT = T.GetField("itemsCollection", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
            Dim ItemCollection As Object = IT.GetValue(CB)
    
            'Get from the itemCollection object, get the field "comparer"
            Dim D As Type = T.GetNestedType("ObjectCollection", Reflection.BindingFlags.Public Or Reflection.BindingFlags.Instance)
            Dim C = D.GetField("comparer", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
    
            'The comparer we just got is a string comparer, it always compare Item.ToString
            'We will replace this comparer by an integer comparer
            C.SetValue(ItemCollection, Comparer)
            'Now that this is done, the integer items will sort 
        End Sub
    End Class
    
    
    
    
    
    
    'This will be the integer comparer that will be injected into our Combobox
    'Note the field combobox and the exposed constructor. Those are required
    Public Class ItemComparer : Implements IComparer
        Private comboBox As ComboBox
    
    
        Public Sub New(ByVal comboBox As System.Windows.Forms.ComboBox)
            MyBase.New()
            Me.comboBox = comboBox
        End Sub
    
        Public Function Compare(ByVal item1 As Object, ByVal item2 As Object) As Integer Implements IComparer.Compare
            If Integer.TryParse(item1.ToString, New Integer) Then
                If Integer.TryParse(item2.ToString, New Integer) Then
                    If Integer.Parse(item1.ToString) > Integer.Parse(item2.ToString) Then Return 1
                    If Integer.Parse(item2.ToString) > Integer.Parse(item1.ToString) Then Return -1
                End If
            End If
            Return 0
        End Function
    End Class

    .


    Luc






    Tuesday, March 21, 2017 9:58 PM
  • Can anyone please tell me how to sort this problem?

    Where do the numbers come from?   If you do not set the combobox Sorted property to true, the numbers will be listed in the combobox in the sequence in which you load them.  If you sort the numbers before you load the combobox, they will stay in that sequence.

    Tuesday, March 21, 2017 10:05 PM
  • I have stored 10 integer items in combo box and also has set the property SORTED =TRUE in the property window.

    And during run time when I view the items in combo box they are listed as

    1

    10

    2

    3

    4

    5

    6

    7

    8

    9

    So the 10th value is listed at 2nd position.

    Can anyone please tell me how to sort this problem?

    Thank you in advance

    Yes that is the right sort order for a string from low to high. 

    It would be different if it was 01, 02, 03................................09, 10


    Success
    Cor

    Tuesday, March 21, 2017 10:58 PM
  • Hi Tabzee,

    Based on your description, you want to sort combox items, I suggest you to load your data in the list<T>, and then sort items by list.sorted event, finally you can add data in combox. please set combox.sorted=false.

    You can refer to the code below.

    Private Sub sortdata()
            Dim list As New List(Of Integer)() From {
        1,
        2,
        10,
        12,
        21,
        8,
        9
    }
            list.Sort()
            Console.WriteLine(list.ToArray())
            Console.ReadLine()
            ComboBox1.Sorted = False
            For Each a As Integer In list
                ComboBox1.Items.Add(a)
            Next
    
        End Sub

    Best Regards,

    Cherry Bu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, March 22, 2017 10:35 AM
    Moderator
  • Maybe this will help?  A guess because the goal is not clear

        Public Sub SortCB(cmbobox As ComboBox)
            cmbobox.Sorted = False
            Dim results As List(Of Integer)
            results = (From item In cmbobox.Items
                      Let i As Integer = CInt(item)
                      Select i).OrderBy(Function(itm) itm).ToList
    
            cmbobox.Items.Clear()
            cmbobox.DataSource = results
        End Sub
    
    
            'to use
            SortCB(ComboBox1)
            SortCB(ComboBox2)
    


    "Those who use Application.DoEvents() have no idea what it does and those who know what it does never use it." - MSDN User JohnWein    Multics - An OS ahead of its time.

    Wednesday, March 22, 2017 11:38 AM
  • Thank you guys for all your help:)

    Every answer was very helpful.

    I wish I would mark everyone answers as MARK AS ANSWER. But unfortunately it is not available. So it would be better I leave this post without marking any answer.

    Thank you:)

    Wednesday, March 22, 2017 7:54 PM
  • I wish I would mark everyone answers as MARK AS ANSWER. But unfortunately it is not available.

    Yes you can: You can mark as many as you want to - that's entirely up to you.

    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Wednesday, March 22, 2017 7:57 PM