I like many others have found a problem with the Silverlight ComboBox. I think the problem can be summed up like this: if a ComboBox is bound to an ItemsSource and a SelectedItem, and the SelectedItem (based on DataContext) is set before the ItemsSource, the item in the list does not get selected when the ItemsSource is set. If you google this problem, you will find plenty of posts about it. As yet, I have not found a definitive answer to this question that does not involve creating a custom control. Here is one thread that I have found useful:
To give you some background on my situation. My ItemsSource is a class called RecordProvider which asynchronously loads its data from WCF and then notifies the bound item through the CollectionChanged event when a record is added or removed the collection. The collection never throws the CollectionChanged event. The CollectionChanged event is never raised with NotifyCollectionChangedAction.Reset because I never clear the list. Every time I clear the list, I remove all the records one by one so that the ComboBox doesn't get a shock.
The selected item is of the same type as the items in the collection and each of the items has Equals() overriden so that the items in the list can be evaluation for equivalence.
What I want to know is - is there a way that I can bind the ItemsSource on a stock standard Silverlight ComboBox to a list of records loaded from WCF and bind the SelectedItem to a property on my DataContext? Is there is defininive answer on this? What does Microsoft recommend? I would really love to read something about what Microsoft says on this topic.
I still wake up in the middle of the night with my heart racing, having just had a nightmare that my app needed another ComboBox. I feel your pain.
I made a discovery in while corresponding with others in this post, and that is if I set SelectedValue rather than SelectedItem, the race condition seemed to be resolved. At least I think it was. I tried several different solutions for it there may have been some remnant hiding in my code that was still working it's magic.
After additional testing on my app, I realized that my problem what not 100% resolved and posted a question about it to the forum. It didn't result in any major breakthroughs though.
In the end, I gave up and loaded the lists I would need when the app started and stored them in a static class and just implemented an IValueConverter for each of my ComboBoxes to set the SelectedItem. This approach is less than ideal and it should never have to be done this way, but it's the only one I've found that has been able to stand up to all my testing.
Last week I did stumble on this post from Jeff Handley which looked promising (Jeff mentions a blog post by Kyle McClellen which is also worth a quick read). In the end, I couldn't get Jeff's solution to port over to my app, but maybe there will be some gems in there for you.
The ComboBox is really such a fundamental control, it's frustrating to not see much response from MS on this. Jeff and Kyle are a good start but I would like to see more, and not limit it to DDS.
"I still wake up in the middle of the night with my heart racing, having just had a nightmare that my app needed another ComboBox. I feel your pain."
Haha. Yes, finally someone who understands what I am going through.We've been developing our Silverlight application for the past year now. I can safely say that between the two programmers here we have wasted months on trying to get ComboBoxes and Cascading ComboBoxes to behave under all conditions and we're still not there.
The fundamental problem with the ComboBox as I see it is that if the DataContext gets set before the ItemsSource, the SelectedItem never ends up getting set. Why doesn't the control just recheck to see if the SelectedItem exists in the ItemsSource when the ItemsSource is loaded? I'm working on seeing if I can get a custom ComboBox to do that. But, I was hoping not to have to create a new control. The standard Silverlight one should just work.
One possible way to solve this problem could be to make sure that the ItemsSource on every ComboBox is set before the DataContext is set on the ComboBoxes.While this is already possible in Silverlight, it's a pain because of the asynchronous nature of Silverlight. One thing up for consideration is the juditious use of synchronous WCF calls:
Take a look at the post I put together on this issue.
There's some RIA Services specific stuff in there, but the Async modes I discuss near the end really make this whole thing a lot simpler.
Who set my last post to Answer? I just don't get it. Why do posts randomly get set to answered when I'm not looking? Who is doing that????
Kyle - thanks heaps. I haven't tried out your library yet, but your approach is fantastic. I didn't even realise you could extend ComboBoxes in that way. I've had some success with a custom control so if I use the same method to extend the ComboBox you are, I might be able to achieve the same effect without resorting to a user control. I will post my results when I have tested a few different things. Good work.