Building Windows Phone applications, you have options for data. Sometimes you might want to use XML files. Warning: using XML files is like serialized Isolated Storage data – you need to load the entire document into memory to filter it. But, what if your data is already XML? You might want to reuse your assets.
In this sample, I will build out a cascading set of pages letting the user pick Country > then Region > then City. It’s a real scenario, not in any way unique to XML-related data.
Let’s create some XML. Here’s the files and data:
Step 1: Simplify your life with Resource Files
It’s my opinion that Resources Files are highly underutilized in the Microsoft developer community. I think they are just misunderstood. Resources Files reference embedded resources through strongly typed interfaces (opposed to some cryptic file path).
Just “Add New Item” and select “Resources File”:
Step 2: Add your XML files to the Resources File
Visual Studio gives a pretty nice to Resources Files. Just double-click it. Select to “Add Resource” and choose “Add Existing File”. This will let you browse to your local XML files and add them (all at once if you want). After that, just Save and Close.
Step 3: Create your Models
You could bind directly to XML in XAML, but since Silverlight 3 (the Windows Phone version of Silverlight) doesn’t have the XmlDataProvider – serializing your XML into classes makes it easier for you to mess with it. Something simple, like this:
Step 4: Make a simple View Model
Once we have a view-model created, we can start to build out our UI. For the sake of this sample, I’ll create a simple view-model. But the sophistication is your discretion. All we need are data properties and loading methods. (Before you start, add references to System.Xml and System.Xml.Linq – you will need those). Like this:
In the code above, take a look at LoadCities(). Here, I use the Resources File to read the Cities.xml file (as a string). Then the XDocument object’s Parse() method turns that string into a DOM we can use Linq to XML against. Using Linq to XML, I filter the data, and then project into the Cities properties an Enumerable of City objects. Presto! Linq is amazing.
Remember, this process is fast. But if you think it will lock the UI too long, you need to convert this into an asynchronous method.
The XAML for the UI is as easy as you want it to be.
In my case, I use a simple <ListBox /> that shows the name of the Country and the regions inside the Country. It would be so much easier for you to add a Flag image or something fancy. But, this is just a sample.
Here’s the XAML:
Here’s the code-behind:
In the code above, take a look at MainPage_Loaded(). Here, I call LoadCountries() which populates the view-model’s Countries property. Setting the LIstBox’s ItemsSource causes the control to bind to the data and render the UI.
Now take a look at MyListBox_SelectionChanged(). This occurs when the user taps on a Country in the ListBox. We build the Address for the SelectRegion.xaml, passing the selected Country code in the Query String. The NavigationService does the rest.
I have intentionally made the XAML of each page in this sample practically identical. This way we don’t focus on the UI, instead we focus on consuming XML.
Uh-oh, we are actually done consuming the XML. The view-model does that. If you are this far, you have graduated! Great work, by the way. Still, for the sake of completeness let’s see the ChooseCity.xaml code-behind:
In the code above, take a look at OnNavigatedTo(). Here, I handle the receipt of the QueryString passed to the page. This method fires every time NavigationServices pushes the user here. The QueryString code is identical to ASP.Net syntax. With those values, I just call the view-model again. It’s that redundant.
In all reality, reading XML in a Windows Phone application is nearly identical to WPF. The framework makes it easy. There are real issues you should consider before using XML. However, if that’s on the menu, it’s easy to swallow – hopefully you agree.