bug when working on selecteditems of listbox?
-
Sunday, May 27, 2012 6:43 PM
When changing selecteditems (the items themselves, not which ones are selected) in a multiselect listbox, sometimes the operation does not happen and items are deselected. Here is a simple example of what I mean, just a form with a multiselect listbox.
Public Class Form1 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load ListBox1.Items.Add("item at index 0") ListBox1.Items.Add("item at index 1") ListBox1.Items.Add("item at index 2") ListBox1.Items.Add("item at index 3") ListBox1.SelectedIndex = 0 ListBox1.SelectedIndex = 1 ListBox1.SelectedIndex = 2 ListBox1.SelectedIndex = 3 For Each index In ListBox1.SelectedIndices ListBox1.Items(index) &= " operated on" Next End Sub End ClassWhen this example runs, items at index 0 and 3 are deselected and item at index 3 is not changed. If this example has more items, the flaw repeats everyother item. Am I missing something and writing bad code, or is this a bug in visual basic itself?
All Replies
-
Sunday, May 27, 2012 7:15 PMYou are aware, I assume, that each time you set the selected index, it's just that - it's changed to whatever you set it to be in code, right?
Please call me Frank :)
- Proposed As Answer by Paul IshakMicrosoft Community Contributor, Moderator Sunday, May 27, 2012 7:51 PM
- Unproposed As Answer by zuckerberg Monday, May 28, 2012 6:47 PM
-
Sunday, May 27, 2012 7:50 PM
I was hoping you'd reply back by now, but at any rate, to make multiple selections with a listbox, use the SetSelected Method. I have an example on a page of my website here (I hate this new code formatter this forum uses now) and following demonstrates it:

Please call me Frank :)
- Proposed As Answer by Paul IshakMicrosoft Community Contributor, Moderator Sunday, May 27, 2012 8:13 PM
- Unproposed As Answer by zuckerberg Monday, May 28, 2012 6:47 PM
- Proposed As Answer by .paul. _ Monday, May 28, 2012 11:49 PM
-
Sunday, May 27, 2012 8:07 PMModerator
Public Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click ListBox1.Items.Add("item at index 0") ListBox1.Items.Add("item at index 1") ListBox1.Items.Add("item at index 2") ListBox1.Items.Add("item at index 3") ListBox1.SelectionMode = SelectionMode.MultiExtended ListBox1.SetSelected(0, True) ListBox1.SetSelected(1, True) ListBox1.SetSelected(2, True) ListBox1.SetSelected(3, True) For I = 0 To ListBox1.SelectedIndices.Count - 1 ListBox1.Items(I) = ListBox1.Items(I).ToString & " operated on" Next End Sub End ClassI just tested it this way too, and this also works:
Public Class Form1 Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click ListBox1.Items.Add("item at index 0") ListBox1.Items.Add("item at index 1") ListBox1.Items.Add("item at index 2") ListBox1.Items.Add("item at index 3") ListBox1.SelectionMode = SelectionMode.MultiExtended ListBox1.SelectedIndex = 0 ListBox1.SelectedIndex = 1 ListBox1.SelectedIndex = 2 ListBox1.SelectedIndex = 3 For I = 0 To ListBox1.SelectedIndices.Count - 1 ListBox1.Items(I) = ListBox1.Items(I).ToString & " operated on" Next End Sub End ClassWhich means that you needed "ListBox1.SelectionMode = SelectionMode.MultiExtended"
If you want something you've never had, you need to do something you've never done. If you believe something to be true, then one day you will be called upon to demonstrate that truth.
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Sunday, May 27, 2012 8:12 PM
- Proposed As Answer by Frank L. SmithMicrosoft Community Contributor Sunday, May 27, 2012 8:15 PM
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Sunday, May 27, 2012 8:22 PM
- Unproposed As Answer by zuckerberg Monday, May 28, 2012 6:47 PM
-
Sunday, May 27, 2012 8:19 PM
When changing selecteditems (the items themselves, not which ones are selected) in a multiselect listbox, sometimes the operation does not happen and items are deselected. Here is a simple example of what I mean, just a form with a multiselect listbox.
Public Class Form1 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load ListBox1.Items.Add("item at index 0") ListBox1.Items.Add("item at index 1") ListBox1.Items.Add("item at index 2") ListBox1.Items.Add("item at index 3") ListBox1.SelectedIndex = 0 ListBox1.SelectedIndex = 1 ListBox1.SelectedIndex = 2 ListBox1.SelectedIndex = 3 For Each index In ListBox1.SelectedIndices ListBox1.Items(index) &= " operated on" Next End Sub End ClassWhen this example runs, items at index 0 and 3 are deselected and item at index 3 is not changed. If this example has more items, the flaw repeats everyother item. Am I missing something and writing bad code, or is this a bug in visual basic itself?
You are writing bad code.
Success
Cor -
Sunday, May 27, 2012 8:23 PM
Hi Zuckerberg
Welcome to MSDN
I assume this is not a bug. Look closely this part of the code
For Each index In ListBox1.SelectedIndices ListBox1.Items(index) &= " operated on" Next
the logic of the code. You can use break point to see what is goin on with the index. I am newbie, so I can only assume.Be a good forum member. Make this forum a great place to meet and interact with others around the world.
Helpful Links: -
Monday, May 28, 2012 6:15 PM
I stepped through the loop and see that the selectedindices collection changes upon certain loops, but I still don't understand why. Please explain.
-
Monday, May 28, 2012 6:16 PMModerator
I think its because before you did NOT have the following line:
"ListBox1.SelectionMode = SelectionMode.MultiExtended"
Comment out that line and see what happens
If you want something you've never had, you need to do something you've never done. If you believe something to be true, then one day you will be called upon to demonstrate that truth.
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Monday, May 28, 2012 6:17 PM
-
Monday, May 28, 2012 6:30 PM
Sorry my code block didn't show it, but I already had the selectionmode set to multi on the [Design] page. That was not my problem.
And changing the for next loop is not the solution I'm looking for. For example, what if there were more items and the selected ones to change were just 1, 3 and 4.
Public Class Form1 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load ListBox1.Items.Add("item at index 0") ListBox1.Items.Add("item at index 1") ListBox1.Items.Add("item at index 2") ListBox1.Items.Add("item at index 3") ListBox1.Items.Add("item at index 4") ListBox1.Items.Add("item at index 5") ListBox1.Items.Add("item at index 6") ListBox1.SelectionMode = SelectionMode.MultiExtended ListBox1.SetSelected(1, True) ListBox1.SetSelected(3, True) ListBox1.SetSelected(4, True) For I = 0 To ListBox1.SelectedIndices.Count - 1 ListBox1.Items(I) = ListBox1.Items(I).ToString & " operated on" Next End Sub End ClassThe for next loop you suggested would just change 0,1 and 2. To change 1,3 and 4, I would think my original for next loop (For each I in ListBox1.SelectedIndices) would work, but 3 gets deselcted and 4 not operated on which is what I don't understand.
- Edited by zuckerberg Monday, May 28, 2012 6:34 PM
-
Monday, May 28, 2012 6:50 PM
Sorry my code block didn't show it, but I already had the selectionmode set to multi on the [Design] page. That was not my problem.
And changing the for next loop is not the solution I'm looking for. For example, what if there were more items and the selected ones to change were just 1, 3 and 4.
Public Class Form1 Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load ListBox1.Items.Add("item at index 0") ListBox1.Items.Add("item at index 1") ListBox1.Items.Add("item at index 2") ListBox1.Items.Add("item at index 3") ListBox1.Items.Add("item at index 4") ListBox1.Items.Add("item at index 5") ListBox1.Items.Add("item at index 6") ListBox1.SelectionMode = SelectionMode.MultiExtended ListBox1.SetSelected(1, True) ListBox1.SetSelected(3, True) ListBox1.SetSelected(4, True) For I = 0 To ListBox1.SelectedIndices.Count - 1 ListBox1.Items(I) = ListBox1.Items(I).ToString & " operated on" Next End Sub End ClassThe for next loop you suggested would just change 0,1 and 2. To change 1,3 and 4, I would think my original for next loop (For each I in ListBox1.SelectedIndices) would work, but 3 gets deselcted and 4 not operated on which is what I don't understand.
I don't know who you're talking to - you seem to have bypassed everything I put yesterday but to answer your question, it makes perfect sense.
Look at what you're doing there - you're not doing anything with the selected items or selected indices; you're getting the count but telling the loop the progress through the listbox from zero to that count (the latter having nothing to do with the SELECTED ones).
Make sense?
Please call me Frank :)
- Proposed As Answer by .paul. _ Monday, May 28, 2012 11:51 PM
-
Monday, May 28, 2012 7:03 PMModerator
OK, so I clearly understand what you are talking about, but I am unsure as to if it is a bug, or simply a mus-implementation of the code.
Anyways, I have taken the liberty to make a little code that better points out the problem. Change the test condiition variable to see.
Very interesting, I will continue to look into this.
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click ListBox1.Items.Add("item at index 0") ListBox1.Items.Add("item at index 1") ListBox1.Items.Add("item at index 2") ListBox1.Items.Add("item at index 3") ListBox1.Items.Add("item at index 4") ListBox1.Items.Add("item at index 5") ListBox1.Items.Add("item at index 6") ListBox1.SelectionMode = SelectionMode.MultiExtended ListBox1.SetSelected(0, True) ListBox1.SetSelected(1, True) ListBox1.SetSelected(2, True) ListBox1.SetSelected(3, True) ListBox1.SetSelected(4, True) ListBox1.SetSelected(5, True) ListBox1.Update() Dim TestCondition As Integer = 1 For Each SelectedIndex As Integer In ListBox1.SelectedIndices Select Case TestCondition Case 1 ListBox1.Items(SelectedIndex) = String.Concat(ListBox1.Items(SelectedIndex), " operated on") MsgBox(SelectedIndex) Case 2 MsgBox(SelectedIndex) End Select Next End Sub
If you want something you've never had, you need to do something you've never done. If you believe something to be true, then one day you will be called upon to demonstrate that truth.
-
Monday, May 28, 2012 7:09 PM
Thats my fault frank haha!
Then you see my point I hope?
For all that's being done, he may as well have the loop set up as "For i As Integer = 0 to 2", because in the code that follows, it's not looking at the selected items, just the items by index number.
Please call me Frank :)
-
Monday, May 28, 2012 7:15 PMModerator
I fully see your point, and I take the blame for that, because he was using for-each originally!Thats my fault frank haha!
Then you see my point I hope?
For all that's being done, he may as well have the loop set up as "For i As Integer = 0 to 2", because in the code that follows, it's not looking at the selected items, just the items by index number.
Please call me Frank :)
If you want something you've never had, you need to do something you've never done. If you believe something to be true, then one day you will be called upon to demonstrate that truth.
-
Monday, May 28, 2012 7:28 PM
I think it's still being missed. As much as I hate this code formatter, it's really nothing more than this:
For Each itm As String In ListBox1.SelectedItems ' Do something Next
Please call me Frank :)
-
Monday, May 28, 2012 7:41 PMModerator
ok try this! The problem was that the SelectedIndices collection would update while you were changing the values in the collection. You need to copy the values of the collection first to an array, then iterate through the copy of the collection instead of directly iterating through the SelectedIndices collection. This is because items become selected/unselected as you change their values. If after you have modified the values that you have selected, you wish them to remain selected, you are going to have to use the copy of the array to return all items to their original selection state.
Option Strict On
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
ListBox1.Items.Clear() 'Clear The Listbox
ListBox1.Items.Add("item at index 0") 'Populate The Listbox
ListBox1.Items.Add("item at index 1")
ListBox1.Items.Add("item at index 2")
ListBox1.Items.Add("item at index 3")
ListBox1.Items.Add("item at index 4")
ListBox1.Items.Add("item at index 5")
ListBox1.Items.Add("item at index 6")
ListBox1.SelectionMode = SelectionMode.MultiExtended 'Set to multiextended
ListBox1.SetSelected(0, True) 'Set the selection state of some items
ListBox1.SetSelected(1, True)
ListBox1.SetSelected(2, True)
ListBox1.SetSelected(3, False)
ListBox1.SetSelected(4, True)
ListBox1.SetSelected(5, True)
ListBox1.SetSelected(6, True)
'Copy all values to an array
Dim Collection(ListBox1.SelectedIndices.Count - 1) As Integer
For I = 0 To ListBox1.SelectedIndices.Count - 1
Collection(I) = ListBox1.SelectedIndices(I)
Next
'cycle through the array
For Each SelectedIndex As Integer In Collection
'concatonate each selected item
'The selected indices collection changes here, as you change values
ListBox1.Items(SelectedIndex) = String.Concat(ListBox1.Items(SelectedIndex), " operated on")
Next
'restore the selected indexs to their original state
For Each SelectedIndex As Integer In Collection
ListBox1.SetSelected(SelectedIndex, True)
Next
End Sub
End Class
If you want something you've never had, you need to do something you've never done. If you believe something to be true, then one day you will be called upon to demonstrate that truth.
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Monday, May 28, 2012 7:49 PM
-
Tuesday, May 29, 2012 12:20 AM
Sorry Frank for replying out of order and the unclear details.
Thanks Paul. I was hoping to avoid duplicating the selectedindices collection needing more variables and lines of code, but can live with it. It still bugs me why with my original and seemingly most efficient for next loop, some items get deselected and not others.
-
Tuesday, May 29, 2012 12:28 AMModerator
Its because you are changing which "index numbers" that are inside the "listbox1.selectedindices" collection. You are not directly changing these numbers, but by editing the value at that index, the listbox automatically is changing the selection state of the item at that index. Each time this happens it updates the listbo's "selectedindices" collection, even if you are in the middle of a loop.Sorry Frank for replying out of order and the unclear details.
Thanks Paul. I was hoping to avoid duplicating the selectedindices collection needing more variables and lines of code, but can live with it. It still bugs me why with my original and seemingly most efficient for next loop, some items get deselected and not others.
If you want something you've never had, you need to do something you've never done. If you believe something to be true, then one day you will be called upon to demonstrate that truth.
- Edited by Paul IshakMicrosoft Community Contributor, Moderator Tuesday, May 29, 2012 12:30 AM
- Marked As Answer by zuckerberg Tuesday, May 29, 2012 2:07 AM
-
Tuesday, May 29, 2012 2:41 AM
After more tinkering, I found a shorter fix.
For Each index In ListBox1.SelectedIndices ListBox1.Items(index) &= " operated on" ListBox1.SetSelected(index, True) NextI guess the setselected line in the loop forces or reminds the system not to change it.

