Silverlight 2: MVVM, Databinding & Cascading ComboBoxes - Part 1
||The article you are reading has moved! It is now available at: http://blog.tinisles.com/2009/02/silverlight-2-mvvm-databinding-cascading-comboboxes-part-1/|
Update: see follow up post to see how I got the cascading ComboBoxes to work: I did mange to get a 'working' solution for cascading ComboBoxes - see the solution here: Silverlight 2: MVVM, Databinding & Cascading ComboBoxes - Part 2
I'm presently working on a Silverlight 2 application at work, and really enjoying the getting into the new technology. Hitting a few issues along the way that are going to make good blog articles when I find the time. This article intends to be the first in a series to demonstrate some of the issues I'm discovering.
Issue no. 1: Databinding Cascading ComboBoxes to a ViewModel.
If you've been following Silverlight 2 developer blogs you'll notice Model-View-ViewModel (MVVM) is a popular separation pattern for UI. Luckily Craig of ConceptDev has already pulled together a good list of links for those wanting to read up on MVVM: Silverlight + Model-View-ViewModel (MVVM). My first introduction to MVVM was the Divelog app from Jonas Follesø. The Divelog app is a good introduction to several concepts: silverlight unit tests, dependency injection, command pattern and MVVM
The actual problem. Let's say we are building an app of all the cities you've visited around the world. The Model classes involved: A Country class contains a collection of Cities, and a Visit class contains references to a Country and a City. The PageViewModel contains: Countries collection of all countries, Visits collection of all visit, and a SelectedVisit property.
...but clicking on the 2nd visit causes the city on the first option to disappear. See a demo of the issue: here.
Anything related to databinding issues is best understood by attaching some 'do nothing' Converter classes. Inside the Converter I've added debugging statements to try work out what order things are happening. The debugging output from the Converters looks like this:
The statements after the red line were created after the second option was clicked. This is how I interpreted the output after the red line:
- The ItemSelected property of the countries ComboBox is set to 'United States'
- The ItemSource property of the cities ComboBox is populated with the cities belonging to the 'United States'
- The interesting bit: ConvertBack is telling us that the city selected in the first option (previously Melbourne) is now null!
My theory: in step number 2 we are changing the contents of a ComboBox still bound to the 'Melbourne' visit. The databinding between the ComboBox and Visit.City fires, cannot find a city in the Visit.Country.Cities and interprets this as null.
The fix.... comes in my next blog post. I've experimented with two approaches for the issue. Approach 1: binding the city ComboBox to a different collection which is temporarily populated with the ALL the possible cities when the PageViewModel.SelectedVisit changes. Approach 2: again populate the city ComboBox will all possible cities - and use databinding to modify the city's visibility.
Grab the source code for this demo: CitiesVisited_step1.zip