Enhancing a Silverlight application converted to run on Windows Phone 7
One of the statements I hear a lot lately is, "If you're a Silverlight developer, then you're already a Windows Phone 7 developer!" Although there are certainly new concepts to learn when moving from Silverlight to Windows Phone 7 development, I've found that general statement to be accurate. Nearly everything you know regarding Silverlight development is applicable when building phone applications. The exception to this rule is Silverlight 4 features, since Windows Phone 7 supports Silverlight 3 plus some additional enhancements.
In my previous article, "Build a Windows Phone 7 Application," I introduced a Windows Phone 7 application that displays albums from Amazon.com in a simulated 3D carousel. The original application was built back in the days of WPF/e before Silverlight, upgraded as new versions of Silverlight came out, then converted to run on the phone. The project conversion took less than one hour (which really surprised me), and I spent another few hours tweaking the code to handle the smaller form factor. I knew that building Windows Phone 7 applications was productive from some previous work I had done, but I hadn't expected the project to convert over so easily. Building Windows Phone 7 applications is certainly a productive process.
In this article, I'll walk through additional features that have been added to the album viewer application. Topics we'll cover include using the Pivot control, navigating between screens using the NavigationService class, and leveraging data binding along with the Model-View-ViewModel (MVVM) pattern. Figure 1 shows the application discussed in my last article.
Figure 1: The Windows Phone 7 album viewer application discussed in this article
Users can search for albums by artist and view a carousel that contains album covers. From there, they can move the carousel right or left using the arrow buttons, and they can select an album to view more information.
The application discussed in this article will keep the initial album carousel screen shown in Figure 1, but it will add an alternate view for users. It will also add an album details screen that shows the album cover, title, pricing, and songs for a given album. Let's start the discussion by covering changes made to the initial screen to give the user more flexibility when viewing albums.
Using the Pivot Control
Windows Phone 7 provides several controls that allow multiple screens to be displayed easily to end users. The first is the Panorama control, which allows users to navigate around a large virtual screen. As they view a section of the screen, a small portion of the remaining screen is shown to the right to let them know that there's more to look at. To understand how a panorama works, imagine a two-foot-wide screen. Placed over it is a phone that can view only a small portion of the screen at once. As users swipe left or right, they can navigate around the screen quickly and easily. The Panorama control is shown in action in Figure 2.
Figure 2: Navigating a large screen using the Panorama control
In addition to the Panorama control, the Pivot control also ships with Windows Phone 7. It provides a simple way for users to navigate between different screens by swiping. You can think of the Pivot control as being analogous to the TabControl found in Silverlight and other frameworks. However, instead of having actual tabs, the Pivot control provides pivot items that display text. The user navigates between pivot items by swiping right or left.
For the updated version of the Amazon Album Viewer application discussed in this article, I decided to use the Pivot control because it provides an intuitive way to navigate between related screens. The first pivot item allows the user to search for artists, and it displays the album carousel once an artist is found. The second pivot item displays the albums in a standard list view. Why would I want two views of the same data? Although the album carousel is fun to play with, people are used to lists and will likely find what they're looking for faster by scanning through albums from top to bottom.
Figure 3 shows how the Pivot control is used in MainPage.xaml. Notice that it has two PivotItem elements defined with it, each containing the screen that should be displayed.
The screen content displayed as a pivot item is selected and placed within the PivotItem start and end tags. Figures 4A and 4B show what the Pivot control looks like in action. As the user swipes from right to left, the List pivot item will be displayed.
Figure 4A: A Pivot control in action with list and search pivot items (screen 1)
Figure 4B: Pivot control showing list and search pivot items (screen 2)
Navigating Between Screens
Although the Pivot and Panorama controls can be used to navigate between screens, there will be times when you need to load a different screen that is not associated with one of these controls. In the album viewer application, I wanted to allow users to be taken to an album details screen called AlbumDetails.xaml when they click the album at the bottom of the Search pivot item or when they click an album in the List pivot item.
Navigating between screens is accomplished using the NavigationService property, which is available through the PhoneApplicationPage class. Both MainPage.xaml, where the Pivot control is used, and AlbumDetails.xaml derive from PhoneApplicationPage, making NavigationService directly accessible. An example of using NavigationService to navigate to AlbumDetails.xaml is shown next:
NavigationService.Navigate(new Uri("/AlbumDetails.xaml", UriKind.Relative));
For the album viewer application, I wanted to create a simple screen navigation service that could be reused across the application. Doing this abstracts the code out of individual pages and places it into a single class, allowing for simplified maintenance. To handle this task, I created a simple singleton class named ScreenNavigator. Because ScreenNavigator doesn't derive from PhoneApplicationPage, I wasn't able to access NavigationService directly. However, you can get to it by going through Application.Current.RootVisual, since the RootVisual of a standard Windows Phone 7 application is a PhoneApplicationFrame type. PhoneApplicationFrame derives from Frame, which exposes the Navigate method used to navigate between screens. Figure 5 shows the simple ScreenNavigator class that I created in the album viewer project. Although it contains only a single navigation method, additional methods could be added to handle navigating between multiple screens.
The following code shows how the ScreenNavigator class can be used to navigate to the AlbumDetails page:
As users select an album, the ScreenNavigator class is used to navigate to a screen that shows album details. They can get back to the search or list screens by clicking the phone's back button. Figure 6 shows an example of the album details screen.
Figure 6: The album details screen displayed by calling the Navigate method
Following the MVVM Pattern
Windows Phone 7 pages provide code-beside files that can be used to retrieve data, manipulate XAML, and perform other functions. The initial version of the album viewer application relied heavily on code-beside files, which work fine but don't promote good code reuse, testing, or simplified maintenance. Having built several Silverlight applications over the past few years, I've come to rely on the MVVM pattern to keep projects modularized and to allow for better code reuse and consistency. I've written about the MVVM pattern in DevProConnections and blogged about different aspects of it as well (see my blog post here), so I won't go into the fundamentals of the pattern here. However, I do want to show you how the initial version of the album viewer application was enhanced to support the pattern.
For the second iteration of the application, I created a MainPageViewModel class to handle retrieving and storing data as a user searches for albums. The class implements INotifyPropertyChanged so that it can be used with data-binding operations and exposes properties, such as Albums, CurrentAlbum and ArtistText that views can bind to. As a user clicks the search button, MainPageViewModel accesses the artist text entered (through a TwoWay binding) and initiates a REST call to Amazon.com. The data that's returned is stored in the Albums property, which is used to render the album carousel and the album list within the Pivot control discussed earlier. Figure 7 shows the portion of the MainPageViewModel class that's responsible for retrieving and storing album data.
Looking through the code, you can see that an AmazonRESTSearch object is created within the constructor and that this object is used to retrieve album data. A Messenger class available with MVVM Light (mvvmlight.codeplex.com) is also used to communicate between the ViewModel and one or more views as data is loaded. For example, the SendLoaderMessage method uses the Messenger class to send a message to a View that is responsible for rendering a loading image and associated animation.
MainPage.xaml binds to MainPageViewModel and relies on it to access album data. The Pivot code shown earlier in Figure 3 demonstrates binding to the Albums property of MainPageViewModel. AlbumDetails.xaml also has a corresponding AlbumDetailsViewModel class that it binds to in order to render album details. The sample code available with this article contains additional ViewModel locator code used to associate ViewModel classes with Views.
A Foundation for Further Phone 7 Development
In this article, you've seen how to use the Pivot control to allow users to switch between screens quickly, how NavigationService can be used to load different screens, and how the MVVM pattern can be used with Windows Phone 7 applications. You can download the code for this article via the Download the Code link at the top of this article. While a lot of work still needs to be done on the album viewer application to make it ready for prime time, the application demonstrates several different Windows Phone 7 features that can be applied in your own applications. I'm still amazed at how easy and productive it is to develop fully functional Silverlight applications that run on a phone!
Dan Wahlin (email@example.com), a Microsoft MVP for ASP.NET, Connected Systems, and Silverlight, founded the Wahlin Group (www.TheWahlinGroup.com), which specializes in .NET, Silverlight, and SharePoint consulting and training solutions. Dan has written several books on .NET, including Professional Silverlight Development and others. He blogs at weblogs.asp.net/dwahlin.