Solved

WPF ListBox SelectedIndex issue

Posted on 2016-07-27
12
32 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 33

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 33

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 33

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
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 

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 33

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 33

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes relatively difficult and non-obvious issues that are likely to arise when creating COM class in Visual Studio and deploying it by professional MSI-authoring tools. It is assumed that the reader is already familiar with the cla…
It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, just open a new email message. In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

895 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

11 Experts available now in Live!

Get 1:1 Help Now