Introduction
There are certain scenarios where we need to display data in a cascading manner. Well Cascading means the values of the next Items Control object is dependent on the current Items Control selected object and so and so forth. In this article we will see how we could do it with List Box and using the powerful Model View View-Model pattern.
Create a WPF Application
Start Visual Studio 2010 and create a WPF application named "CascadingListBox".

The Importance of Model
Well Models represent the data types we are going to deal with in our ViewModel, let's take a simple Task model which has TaskDate and Description as two simple properties.
As you see in above Model structure; the TaskDate is of type DateTime. There might be scenarios where we have to filter the data based on the date. I mean to say the year, month, and day. This would be our objective for the cascading list box.
So we would have Years, Months and Days and finally based on the selection of the day the Tasks would be displayed or you could say filtered.
Add a simple View
Let's add a simple view where it meets the objective. Have three Four list boxes. I have kept it simple, and later we would see how to change the style of the list box.

As you see above the List Boxes are self-explanatory.
The Mighty ViewModel
As you know ViewModel is the primary object of a Model View ViewModel pattern, we would create a ViewModel name it as "MainViewModel". The view model as always implements the INotifyPropertyChanged interface, which would implement the PropertyChangedEvent Handler.
This view model would have four collection properties such as Years, Months, Days and Tasks.
As you see above the INotifyPropertyChanged interface is in action by using the method which would raise the notify event, the Years, Months and Days are IEnumerable of type int; as the Year, Month and Day are int type in a DateTime object.
Now, we would have three Selected properties of type int, such as SelectedYear, SelectedMonth, and SelectedDay. As we are doing a cascading list box approach, we should have these properties that would make the next collection available. Most importantly we would take the nullable types as the Selected Item could be null. If we do not use nullable types the ListBox would have an error, which could be easily identified with a red border around the List Box, to avoid that this nullable type is used.
Let's discuss the SelectedYear property, what should it do? Well on selection of a year I need to display all the months in the year available in the Tasks Collection. Also when a Year is changed from the collection the SelectedMonth would be null and the further two collections would be null as well.
As you see above we are doing a simple linq query to filter and distinct the months collection. The distinct is used to eliminate the repeat of months; as we could expect multiple tasks for a specific day.
Then we have SelectedMonth property which has the similar approach we did for SelectedYear.
When the SelectedMonth is having a valid value, the Days collection is reflected in the list box. So this is the final stage where we select a date and the task(s) is/are displayed in the Tasks List Box.
As you see in the above SelectedDay property, we have a check with the data where it matches with the SelectedYear, SelectedMonth and the SelectedDay. Then the linq query would give us the filtered data for Tasks List Box.
You might be wondering from where the Years list is generated, well of course it is initialized in the constructor of the view model.
Also we have sample data for the TempTasks collection, which was being used in above properties.
So here we are filtering the years from the collection with distinct years.
Binding the ViewModel with View
The view model binding with the view is very easy, just create an instance of the ViewModel in the constructor of the view and set the data context of the view to the view model instance.
As simple as that.
Now we would add the Binding in the xaml view.
The above Years List Box shows that the Items Source binding should be One Way which is default, and the SelectedItem Binding as Two Way, because the view model needs to know what the user has changed in view (It is only required where we need to know what the user would change). We would do the same for the rest of the List Boxes respectively.
You might be wondering that, the months could be displayed as a short abbreviated string. Well if you need to display like that; you need a converter.
Add a converter name it as "ShortMonthNameConverter". (This is a class where IValueConverter interface is implemented)
As you see in the above converter the conversion is done very easily.
Now to use a converter, you need to add it to the specific xaml page where it would be used.
Well before that you need to add the namespace where the class is referred.
So we are ready to test the application.



Let's spice it up a bit more, let's add a style for the List Box.
I am going to add the Expression dark theme for the List Box, here is the trick for optimization; if you use themes for specific controls add the specific styles to the app.xaml or resource dictionary.
For this purpose I have included the List Box Item, Nuclear Thumb, Repeat Button, Nuclear Slider Thumb, Nuclear Scroll Bar Repeat Button, Scrollbar, and Nuclear Scroll Viewer styles to the app.xaml.
After adding the styles to the application, the new look and feel would be like following:

If you remove the Background brush, Border Brush and the Border Thickness then the style would look like the following:

Conclusion
We have successfully made the cascading list box using Model View View-Model pattern. This concept could also be used for Combo Box. Also this could also be used for Silverlight, however the styles needs to be changed accordingly.
About Diptimaya Patra
 |
Diptimaya Patra is a Client App Dev MVP, also a software consultant in the following areas: Silverlight, WPF, Expression Blend, Windows Phone 7.
Follow him in tweeter @dpatra
This author has published 13 articles on DotNetSlackers. View other articles or the complete profile here.
|
You might also be interested in the following related blog posts
ASP.NET: trigger cross-page postback on ListBox selection change
read more
Asynchronous Data Binding in Windows Presentation Foundation
read more
Host WPF Controls in Windows Forms
read more
Using WPF, Virtual Earth, and WPF/E together...
read more
More WPFE, Virtual Earth, and AJAX goodness!
read more
WPF/E and Script#
read more
Go XBAP, WPF/E and Big Screen Photos! Aussie Aussie Aussie...
read more
You gotta love SeeWindowsVista
read more
|
|
Please login to rate or to leave a comment.