Tim Tim - 3 months ago 22
C# Question

listBox selectedIndex is always 0 unless I make the thread wait

I have a listBox populated manually. When a user selects an item I use the value of the selected index to recreate the list with new data. However, it always seems to return 0 unless I put a breakpoint in. With the breakpoint it works perfectly. I looked at the question: WPF ListBox SelectionChanged event and the suggestion to make the thread sleep for 70ms works most of the time. 200ms works even more reliably!!

I am guessing this is a threading issue but I don't know how to make the event handler wait for the selection event to finish properly other than Thread.Sleep() which is obviously unsatisfactory.

I tried to use e.AddedItems but that had the same problem - no AddedItems until the event completed. I had to make the thread sleep to ensure there was something to work on. This is my code for the event handler:

private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (listBox.SelectedIndex != -1)
{
selectedTopicID = listBox.SelectedIndex;
listBox.Items.Clear(); //Breakpoint at start of line will fix issue
foreach (Skill skill in setOfSkills)
{
if (skill.topicID == selectedTopicID)
{
string skillName = skill.skillName;
ListBoxItem nextSkill = new ListBoxItem();
nextSkill.Content = skillName;
nextSkill.Height = 50;
listBox.Items.Insert(0, nextSkill);
}
}
currentList = CurrentListType.Skill;
}
}


Any advice gratefully received.

in response to KANAX I added a Console output of the SelectedIndex and got this when I selected the 5th item:

enter image description here

The App is then displaying the contents from the first item.

Tim Tim
Answer

The trick is to check that ListBox.SelectedIndex != -1 before running the code in the event handler and then set it to -1 at the end of the event handler code. I have also decided to Tag the list box items as they are loaded to the list and use the Tag rather than the actual index location.

ListBox sendingListBox = (ListBox)sender;    
if (sendingListBox.SelectedIndex != -1)
{
    ListBoxItem selectedItem = (ListBoxItem)e.AddedItems[0];
    selectedTopicID = (int)selectedItem.Tag;
    //My code to do stuff
    sendingListBox.SelectedIndex = -1;
}