EspertoDiProgrammazione EspertoDiProgrammazione - 1 month ago 10
Vb.net Question

Sorting value in the combobox without losing the indexes which are associated

In my app I make a code that get content from web page.
The team name that was get from web, is order in combobox in sequentially mode, that's as they are read.
I store the value read in

Classifica_Table
, so I execute this code for adding the value:

For Each Team As Team_Data In Classifica_Table
ComboBox1.Items.Add(Team.Name) 'Populate Combo Boxes with team names
Next


Now I own something like Juventus, Roma, Inter that are messy and not in order of alphabet.
I tried to order them in the past with something like:

For Each Team As Team_Data In Classifica_Table.OrderBy(Function(x) x.Name)
ComboBox1.Items.Add(Team.Name)
Next


This worked only for the look and feel, because the indexes within the table are lost.
For example if I have associated:

Juventus => 3

Rome => 5

Inter => 2

I find myself into:

Inter => 3

Juventus => 5

Rome => 2

as it should be:

Inter => 2

Juventus => 3

Rome => 5


Would there be a way to sort the values without losing the indexes they are associated?
More details:


Dim Classifica_Table() As Team_Data


The index of each team is associated with this:


Classifica_Table(ComboBox1.SelectedIndex).Partite_Giocate


and
.Partite_Giocate
is a variable that is enhanced during the download of the data.
Complete structure of the code:

1. Adding data download in the combobox:

Classifica_Table = Fill_Table(Classifica_JS)

ComboBox1.Items.Clear()
For Each Team As Team_Data In Classifica_Table
ComboBox1.Items.Add(Team.Name) 'Populate Combo Boxes with team names
Next


2. Fill table valorize the variable of each "teams", so i've this variable valorized with data from internet:

.Partite_Giocate..
.Vincite..
.Pareggi...
.Perdite...
.Goal_Segnati..
.Goal_Subiti...


This is a integer variable

3. Index of each teams in combobox:

Classifica_Table(ComboBox1.SelectedIndex).Partite_Giocate


And so on.. that's it.

Answer

SelectedIndex is a property that keep track of the position of the item selected in the combobox items, it is not to be used as an index in another collection.

If you want to keep a value associated with your displayed item (Name) then the approach to add items to your combo should be substituted with a DataBinding approach;

Dim bs = new BindingSource()
bs.DataSource = Classifica_Table.OrderBy (Function(x) x.Name)
ComboBox1.DataSource = bs
ComboBox1.DisplayMember = "Name"
ComboBox1.ValueMember = "Partite_Giocate"

Remember that this method now requires a reevaluation of every point where you read values back from the combobox. Now your ComboBox Items are instances of a Team class and you get them back using the SelectedItem property with a DirectCast to Team. To get the Value of an Item you read the SelectedValue property and so on...

So for example, if you want to track the combobox change event you could write

Sub comboBox_SelectedIndexChanged(sender as Object, e as EventArgs) 
    Dim b = DirectCast(sender, ComboBox)
    if b.SelectedItem IsNot Nothing Then
        Dim t = DirectCast(b.SelectedItem, Team)
        Console.WriteLine("Partite Giocate=" & t.Partite_Giocate)

    End If 
End Sub

EDIT Looking at your project, this is an example on how I would change your code in the SelectedIndexChanged of the ComboBox1. In that method you use the SelectedIndex values as an index to the Classifica_Table array of structure. This is wrong of course you want to rearrange the display of the Teams in your combo. Instead, you should try to find the current selected Team_Data value using the Name because this is an unique value in your combo.

Private Sub ComboBox1_SelectedIndexChanged(.....) Handles ComboBox1.SelectedIndexChanged 
    If ComboBox1.SelectedIndex = ComboBox2.SelectedIndex Then 
       MsgBox(".....") 
       Exit Sub 
    End If 

    ' Get the Team_Data corresponding to the Text currently selected    
    Dim td = Classifica_Table.Where(Function(x) x.Name = ComboBox1.Text).SingleOrDefault() 
    Dim Shield As Bitmap = Bitmap.FromStream(New MemoryStream(New WebClient().DownloadData(td.Shield))) 
    Shield_1.Image = Shield 
    Rating_1_1.Value = td.Partite_Giocate 
    Rating_1_2.Value = td.Vincite 
    Rating_1_3.Value = td.Pareggi 
    Rating_1_4.Value = td.Perdite 
    Rating_1_5.Value = td.Goal_Segnati 
    Rating_1_6.Value = td.Goal_Subiti
    .....

Of course with this approach you don't need to use the DataBinding feature and you could sort your Teams because the retrieve of the Team_Data to use no more use the SelectedIndex property

Comments