none
ComboBox with Custom Sorting (not bound) RRS feed

  • Question

  • I have a ComboBox with Items which look like this

    0 - unused, 1, 2, 3, ..., 10, 11, 12, ..., 20, 21, 22, ...

    so all integers except for that first entry ("0 - unused").  I want to keep the items Sorted, but because they have to be strings (because of the first entry) they do not sort correctly.

    My searches have not turned up a solution.  But this interesting article, http://msdn.microsoft.com/en-us/library/ms996467.aspx#sorting_customfeatures ("Sorting ListView Items by Column Using Windows Forms"), might be what I am looking for EXCEPT for the fact that it pertains to ListView.

    It gets into an area, IComparer, which I've come across before but have little experience with.  So I am asking here if I can use this technique (as described in the article) for ComboBox?

    Thanks,  Bob

    Sunday, August 4, 2013 2:28 PM

Answers

  • Seems that you have to remove the Sorted flag, then use your own Add function while adding new items:

           Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

                  Add(4)

                  Add(2)

                  Add(3)

                  Add(1)

                  Add(5)

                  Add(0)

                  Add(14)

                  Add(12)

           End Sub

           Private Sub Add(ByVal v As Integer)

                  Dim s = New SpecialInt(v)

                  Dim z = cb1.Items.Cast(Of SpecialInt)().Select(Function(item, index) New With {item, index}).FirstOrDefault(Function(p) v < p.item.Value)

                  If z Is Nothing Then

                         cb1.Items.Add(s)

                  Else

                         cb1.Items.Insert(z.index, s)

                  End If

           End Sub

    • Marked as answer by eBob.com Monday, August 5, 2013 1:59 PM
    Monday, August 5, 2013 5:51 AM

All replies

  • I came up with a solution to this, I guess similar to, or certainly inspired by, the article referenced above, ... except that it doesn't work.  And I can't see how/why it doesn't work.

    Code is below.  But my idea was to put objects of type SpecialInt into the list and provide a ToString to append the text to 0.  But I thought that since the framework would have no idea how to sort items of type SpecialInt that I'd have to implement IComparer.  But my Compare function is not being called.  The list is being sorted but as strings. 

    Why doesn't this work?  And if this isn't going to work what alternatives do I have?

    Thanks,  Bob

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Public Class Form1
    
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
            cb1.Sorted = True
            cb1.Items.Add(New SpecialInt(4))
            cb1.Items.Add(New SpecialInt(2))
            cb1.Items.Add(New SpecialInt(3))
            cb1.Items.Add(New SpecialInt(1))
            cb1.Items.Add(New SpecialInt(5))
            cb1.Items.Add(New SpecialInt(0))
            cb1.Items.Add(New SpecialInt(14))
            cb1.Items.Add(New SpecialInt(12))
        End Sub
    End Class
    
    Public Class SpecialInt
        Implements IComparer
        Public Value As Integer
        Public Sub New(pValue As Integer)
            Value = pValue
        End Sub
        Public Function Compare(x As Object, y As Object) As Integer _
                                Implements System.Collections.IComparer.Compare
            Dim returnVal As Integer = -1
            returnVal = Compare(DirectCast(x, SpecialInt).Value, DirectCast(y, SpecialInt).Value)
            Return returnVal
        End Function
        Public Overrides Function ToString() As String
            If Me.Value = 0 Then : Return "0 - unused"
            Else : Return Me.Value.ToString
            End If
        End Function
    End Class

    Sunday, August 4, 2013 4:31 PM
  • Try this:

        Public Class SpecialInt

            Implements IComparable

            Public ReadOnly Value As Integer

            Public Sub New(pValue As Integer)

                Value = pValue

            End Sub

            Public Overrides Function ToString() As String

                Return If(Value = 0, "0 - unused", Value.ToString)

            End Function

            Public Overloads Function CompareTo(ByVal obj As Object) As Integer _

                   Implements IComparable.CompareTo

                Dim z = DirectCast(obj, SpecialInt)

                Return Value - z.Value

            End Function

        End Class


    • Edited by Viorel_MVP Sunday, August 4, 2013 4:46 PM ....
    Sunday, August 4, 2013 4:45 PM
  • Thank you Viorel but it produces the same result as what I tried.  And, as with my code, your CompareTo function is not being called.

    Bob


    • Edited by eBob.com Sunday, August 4, 2013 7:40 PM
    Sunday, August 4, 2013 7:39 PM
  • Seems that you have to remove the Sorted flag, then use your own Add function while adding new items:

           Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

                  Add(4)

                  Add(2)

                  Add(3)

                  Add(1)

                  Add(5)

                  Add(0)

                  Add(14)

                  Add(12)

           End Sub

           Private Sub Add(ByVal v As Integer)

                  Dim s = New SpecialInt(v)

                  Dim z = cb1.Items.Cast(Of SpecialInt)().Select(Function(item, index) New With {item, index}).FirstOrDefault(Function(p) v < p.item.Value)

                  If z Is Nothing Then

                         cb1.Items.Add(s)

                  Else

                         cb1.Items.Insert(z.index, s)

                  End If

           End Sub

    • Marked as answer by eBob.com Monday, August 5, 2013 1:59 PM
    Monday, August 5, 2013 5:51 AM
  • Thank you Viorel for your continued interest and support.  Of course I was hoping to take advantage of the Sorted property.  Your solution looks very interesting, but I have to confess that I still have not learned linq so I really don't understand what it is doing.  But if I have to give up on Sorted I can implement something using the various Items methods to maintain the list in a sorted order. 

    Thanks again for your interest and help.

    Bob

    Monday, August 5, 2013 1:59 PM