Solved

WPF ListBox SelectedIndex issue

Posted on 2016-07-27
12
23 Views
Last Modified: 2016-08-05
I am setting the selected index of a bound listbox in my code behind in response to some processing that has happened. I can trace the code through and it is only setting the selected index once, the changed event for the selected index fires twice, the first time it is the value my code sets it to and the second time it is -1.

Since the code to do this is through a mixture of several objects it is hard to post an example here. Perhaps someone can give me a clue of how to debug this, or suggest why the selection I make is apparently getting reset by the listbox.

Thanks,
Sid
0
Comment
Question by:Sid Price
  • 7
  • 5
12 Comments
 
LVL 32

Expert Comment

by:sarabande
ID: 41733082
the first time it is the value my code sets it to and the second time it is -1.
what do you mean by 'bounded' listbox?

if somewhere a selection of -1 index is made, the listbox has no selection. after this, you could set the selection again.

so you could do the following:

instead of setting the selected index in the first case, you only save the index to select in a member variable or some other shared variable. when the change event with -1 was occuring you now set the selected index. be aware that the event was fired again after this.

if you want to find out which statement was causing the reset of the listbox you may add a static control to your form. in your code now write log messages to the static control at points where you think the listbox might get changed. if the -1 was selected, you break in the debugger and can see from the current log message which statement may have issued the reset of the listbox. you also can see into the stack where you should see perhaps which messages have been processed before. perhaps you have to add further log messages (or use a listbox for the messages) to narrow down the crucial code sequence..

Sara
0
 

Author Comment

by:Sid Price
ID: 41733093
Hello Sara,

I mean the listbox is data-bound to a Collection:

		listCues.ItemsSource = theCueList
		listCues.DisplayMemberPath = "DisplayLine"
		Dim sortDecsription As New SortDescription("ID", ListSortDirection.Ascending)
		listCues.Items.SortDescriptions.Add(sortDecsription)

Open in new window


instead of setting the selected index in the first case ...

If my code does not set the selected index the change to -1 does not happen so your suggested work-around cannot be used.

if you want to find out which statement  ...

I have used the debugger to stop when the "selected index changed" event occurs, looking at the call stack does not show where the "-1" coming from. It appears that the -1 gets set very quickly after I see the right value gets set and the code has not returned to my code before the -1 is set.

This is very confusing, thanks for helping,
Sid
0
 

Author Comment

by:Sid Price
ID: 41733176
Sara,
I am not sure if this helps but I made a DebugView log of the issue. First a short description of the path to selecting the list item.

My "Sequencer" class detects that a change of selection is required and it raises an event to request this is done. The "PlayManager" class catches this event and in turn raises an event to request the the listbox item selection. In the "MainWindow this last event is processed and the listbox selection is made. I added messaging before and after each "RaiseEvent", plus in the "MainWindow" processing of the selection:

[5240] Sequencer::SequenceFromThisCue (Before event) - selected cue 3 
[5240] PlayManager::HandleSelectThisCue (Before event) - selected cue 3 
[5240] MainWindow::HandleSelectThisCue (Entry) - selected cue 3 
[5240] MainWindow::HandleSelectThisCue - selected cue index2 Calling listCues.SelectedIndex = cueIndex 
[5240] MainWindow::listCues_SelectionChanged - selected index 2 
[5240] MainWindow::HandleSelectThisCue - selected cue index2 After listCues.SelectedIndex = cueIndex 
[5240] MainWindow::HandleSelectThisCue (Exit) - selected cue 3 
[5240] PlayManager::HandleSelectThisCue (After event) - selected cue 3 
[5240] MainWindow::listCues_SelectionChanged - selected index -1 
[5240] Sequencer::SequenceFromThisCue (After event) - selected cue 3 

Open in new window


The only place in my project that the selected index is changed is in "MainWindow" class and as you can see that method is only called once and with the correct selection.

Note that the "SelectionChanged" event is happening twice, once when I select the item requested and once to -1 so some reason.

I hope this helps understand what I am seeing.
Thanks again,
Sid
0
 
LVL 32

Expert Comment

by:sarabande
ID: 41733259
MainWindow::listCues_SelectionChanged - selected index -1
could it be that it happened cause the data were reloaded from database? do you have any Code which makes the bound control 'dirty'?

If my code does not set the selected index the change to -1 does not happen so your suggested work-around cannot be used.
you could set the selected index a second time when -1 was selected ... that is not nice but might work.

Sara
0
 

Author Comment

by:Sid Price
ID: 41733357
could it be that it happened cause the data were reloaded ...

No the Collection is loaded once on startup from a file.

you could set the selected index a second time ...

Well this is a pretty awful hack but at least I can move forward with my design while I continue to try to find the real solution. Here's what I added to the changed event:

	Private useThis As Integer
	Private Sub listCues_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles listCues.SelectionChanged
		Dim iIndex As Integer = listCues.SelectedIndex
		If iIndex = -1 Then
			listCues.SelectedIndex = useThis
		Else
			useThis = iIndex
		End If
		Debug.WriteLine("MainWindow::listCues_SelectionChanged - selected index " & iIndex)
	End Sub

Open in new window


Any further ideas on the real problem here would be much appreciated,
Sid
0
 
LVL 32

Expert Comment

by:sarabande
ID: 41733447
ok. if we take for granted that your first selection also is the trigger for the reset, you first should guarantee that

   - the select is the last statement operating at the listbox in the function
     MainWindow::HandleSelectThisCue

  - that the handler MainWindow::listCues_SelectionChanged  does nothing for this case

  - and returns 'Event successfully handled' if that is possible.

Sara
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:Sid Price
ID: 41733481
the select is the last statement operating  ...

Here is the full code of MainWindow::HandleSelectThisCue:

	Private Sub HandleSelectThisCue(ByVal sender As Object, ByRef thisCue As Cue) Handles mPlayManger.SelectThisCue
		If theCueList.Contains(thisCue) = True Then
			Dim cueIndex As UInt32 = theCueList.IndexOf(thisCue)
			listCues.SelectedIndex = cueIndex
		End If
	End Sub

Open in new window


that the handler MainWindow::listCues_SelectionChanged  does nothing for this case

Not sure what this means, I posted the full code of MainWindow::listCues_SelectionChanged previously.

and returns 'Event successfully handled' if that is possible

The events are "Sub" methods so there is no return value.

Sid
0
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 500 total points
ID: 41733556
that the handler MainWindow::listCues_SelectionChanged  does nothing for this case
should mean that no further action was issued from this handler in this case. that seems to be the case if 'useThis' is only a helper.

The events are "Sub" methods so there is no return value.
native winapi allows to stop a cascade of windows messages by returning 'successfully handled'.

listCues.SelectedIndex = cueIndex
how do you guarantee that an index valid for theCueList also is valid for listCues ?

what is the relation between theCueList and listCues?

can you post all functions where  listCues was used somehow?

Sara
0
 

Author Comment

by:Sid Price
ID: 41733581
native winapi allows to stop a cascade of windows messages ...

This is a vb.net/WPF application, one cannot have return values on events.

how do you guarantee that an index valid for theCueList also is valid for listCues ?

The listbox is sorted by the Cue identity and these are always ascending in the input file that is read into the Collection.

can you post all functions where  listCues was used somehow?

	Private Sub MainWindow_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
		'
		' Test the cues loading
		'
		theCueList.Load("C:\DataRoot\Projects\cueassistv2.0\CueAssistv2.0\CueAssistv2.0\Shows\AvianAmb_001.aap")
		mPlayManger.CueList = theCueList
		listCues.ItemsSource = theCueList
		listCues.DisplayMemberPath = "DisplayLine"
		Dim sortDecsription As New SortDescription("ID", ListSortDirection.Ascending)
		listCues.Items.SortDescriptions.Add(sortDecsription)
	End Sub

	Private Sub btnPlaySelected_Click(sender As Object, e As RoutedEventArgs) Handles btnPlaySelected.Click
		If listCues.SelectedIndex <> -1 Then
			Dim oCue As Cue = listCues.Items(listCues.SelectedIndex)
			mPlayManger.PlayFromThis(oCue)
		End If
	End Sub

	Private Sub HandleSelectThisCue(ByVal sender As Object, ByRef thisCue As Cue) Handles mPlayManger.SelectThisCue
		If theCueList.Contains(thisCue) = True Then
			Dim cueIndex As UInt32 = theCueList.IndexOf(thisCue)
			listCues.SelectedIndex = cueIndex
		End If
	End Sub

	Private Sub listCues_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles listCues.SelectionChanged
		Dim iIndex As Integer = listCues.SelectedIndex
		If iIndex = -1 Then
			listCues.SelectedIndex = useThis
		Else
			useThis = iIndex
		End If
	End Sub

Open in new window

0
 

Accepted Solution

by:
Sid Price earned 0 total points
ID: 41736781
Sara,
Just a short note to let you know that I have resolved the issue you were kindly trying to assist with. I ended up data binding the "SelectedIndex" property of the listbox to a "CurrentIndex" property on the object that manages the collection. Initially I left the "work-around" code in that you suggested, however later when I set a breakpoint in that method the "correction" code that ran when the index was -1 was never getting executed. I have removed that work-around and the data binding continues to work.
Thanks for trying to help, it is much appreciated.
Sid
0
 

Author Closing Comment

by:Sid Price
ID: 41743967
I came to the fix through my own research and work.
0
 
LVL 32

Expert Comment

by:sarabande
ID: 41744017
Congratulations. It is great that you found a good solution and could remove the hack.

Sara
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now