This tutorial begins the discussion of lists and of presenting the ubiquitous Master/Detail relationship in data.
To do this, we’ll revisit the Nerd Dinner application, this time using the Beta Refresh and making sure we focus on best practices, especially the use of MVVM, as we go.
To begin create a new application, using the Windows Phone List Application template. Name it NerdDinnerOne. Update the text properties of the ApplicationTitle and ListTitle to “Nerd Dinner” and “All Dinners” respectively.
Hey! Where’s The oData?
This tutorial was to update the previous version and include a call out to the oData web service for Nerd Dinner. It turns out there is a temporary bug in the Beta (described here) that prevents using oData easily with the simulator, or at all on the phone.
Rather than taking you down a temporary rat-hole, I’d rather finesse that issue for now, and we’ll use the sample data provided by the template (nice, that!).
Press F5, hey! presto! it woiks! Thanks for joining me, Next week….
When you stop the application, do not close the simulator. |
Creating the Details Page
The next step is to create the details page which we’ll transfer control to, when the user selects an item in the ListBox.
Oh, hey! the details page was created for you by the application, called conveniently enough, DetailsPage.xaml. Also nice.
Open the details page and change MY APPLICATION to Nerd Dinner in the ApplicationName TextBlock but notice that the ListTitle is bound to LineOne of the bound object. That is just right, when we have the oData working, we’lll bind to the name of the dinner.
Okay, time to press F5 again. Now you can click on any entry in the list and see the details. Press the back arrow (bottom left of the device) to return to the list.
The View Model
While the application created a View Model (VM) file for the first page, it did not do so for the details page. Let’s create DetailsPageViewModel.cs in the ViewModel folder. The advantages of doing so are laid out in some detail in my posting MVVM – It’s Not Kool-Aid, but the short answer is that the code is more maintainable and more testable.
Transitioning the Code
The list template creates the list for the master , and the details page for the… details. The code behind for the details page looks like this,
DetailsView.xaml.cs
protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); string selectedIndex = ""; if ( NavigationContext.QueryString.TryGetValue( "selectedItem", out selectedIndex)) { int index = int.Parse(selectedIndex); DataContext = App.ViewModel.Items[index]; } }
The essence of MVVM is to move as much as possible of the logic out of the view and into the view model. In that spirit we’ll move the logic for obtaining the new data context out of the view and into a static method in the view model (we do need to pass the current navigation context as that is an artifact of the view and we don’t want the vm reaching up into the view where it doesn’t belong. Here is the complete DetailsPageViewManager,
DetailsPageViewManager.cs
using System; using System.Windows.Navigation; namespace NerdDinnerOne.ViewModels { class DetailsPageView { public static ItemViewModel GetDataContext(NavigationContext navContext) { if ( navContext == null) { throw new ArgumentNullException("Navigation Context was null"); } string selectedIndex; if (navContext.QueryString.TryGetValue("selectedItem", out selectedIndex)) { int index = int.Parse(selectedIndex); return App.ViewModel.Items[index]; } else throw new ArgumentException("The selected index did not find an item"); } } }
The codebehind in DetailsPage.xaml.cs now is much simplified,
DetailsView.xaml.cs Revised
protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); DataContext = ViewModels.DetailsPageView.GetDataContext( this.NavigationContext); }
@toolsche
Actually, it is worse than that; I have to review the code, but I suspect it should have been named DetailsPageViewModel. Argh.
@TMC
It’s the DetailsPageViewManager which just connects the DetailsView with the chosen ItemViewModel of the selected item. Maybe Jesse meant to name it DetailsPageViewModelManager and mixed it up somehow.
Hi Jesse,
On thing is confusing me here – so you have a VM called DetailsPageViewManager but you set the DataContext of the detail page to a different VM (ItemViewModel) – I thought a View should only have 1 VM? (I’m still getting to grips with MVVM!)
not bad .
So which is it?
Let