In my previous article, "Getting Started with Windows Phone 7 Development," I provided an overview of functionality available in the new Windows Phone 7 framework and showed sample code to help get you started using a few of the built-in features. There are a lot of great features in the framework that allow you to interact with phone services, contacts, music, email, distributed data, and more. Figure 1 shows an overview of the frameworks and features available.
Figure 1: Image of Windows Phone 7 Frameworks provided in the framework documentation at msdn.microsoft.com/en-us/library/ff402531(v=VS.92).aspx
In this article, I'll walk through the process of building a Windows Phone 7 application that allows users to search albums from Amazon.com and to view details about individual albums. Data will be retrieved using a REST API exposed by Amazon.com and displayed using a simulated 3D carousel. The initial incarnation of the application discussed here will have one screen and work only in portrait mode. Future articles will enhance the application and take advantage of additional Windows Phone 7 features. This article assumes that you're already familiar with Silverlight development and demonstrates that coding is similar between Windows Phone 7 and standard Silverlight applications.
Figure 2: A Silverlight album viewer application
The overall goal of this article is to convert the existing application to run on Windows Phone 7 and worry about enhancements and modifications later.
The Windows Phone 7 version of the application discussed here provides similar functionality. Users can enter an artist that they'd like to search for, and the application will retrieve album details, including images, pricing, reviews, and more from Amazon.com. As the user selects an album or moves the albums around in the carousel, details will be shown at the bottom of the interface. Figure 3 shows an example of the phone application's interface.
Figure 3: The Windows Phone 7 album viewer application
Creating the Windows Phone 7 Project
After installing the Windows Phone 7 tools for Visual Studio 2010, available from the MSDN App Hub, you'll see several different phone project types when creating a new project. For the album viewer application, I selected the standard Windows Phone Application template as shown in Figure 4, and I named the project WP7AlbumViewer.
Figure 4: The Windows Phone Application template
This project template provides you with a single screen initially, but additional screens can be added as needed. Navigation between screens is accomplished by using the NavigationService object. In a future article, I'll add additional screens into the application, but for those who just can't wait, here's an example of using the NavigationService object to navigate between screens:
NavigationService.Navigate(new Uri("MyScreen.xaml", UriKind.Relative));
Before moving on, let's briefly discuss the other project templates available. The Panorama and Pivot application templates help get you started using those respective controls (see my previous article for details on the differences between the controls) and automatically add collection controls and sample data so that you can visually see the application in action at design time. The databound application template provides a nice starter project for working with data-centric applications and includes a data list screen along with a details screen.
Once a Windows Phone Application project is created, you'll see a MainPage.xaml file in the project that serves as the initial screen. Looking at the document's root element, you'll notice that it's PhoneApplicationPage instead of UserControl or Page as in standard Silverlight applications. PhoneApplicationPage provides functionality specific to Windows Phone 7, such as navigation services, orientation awareness, gesture support, and access to the application bar.
For the sample application, I wanted a blue background to be used within MainPage.xaml, so I created an Images folder and added the desired background .png file (1024 x 768 in size) into it along with additional image files to handle navigation, loading, and other aspects of the application. Each file was marked as a Resource in the Properties window. By using a background image and applying custom colors, I'm overriding the theme selected by the user. But in this case, I want the application to have a specific look and feel. Although themes won't be discussed here, you can find additional information about them at the Themes for Windows Phone page on MSDN.
Once the images were added, I opened MainPage.xaml and added the XAML shown in Figure 5 to create two rows in a Grid, to assign the background image, and to define a TextBlock used for the title area of the application. Figure 6 shows what the application looks like in the Visual Studio designer after the XAML is added.
Figure 6: Customizing the application with text and a background image
Displaying an Album in the Application
The overall goal of the Amazon Album Viewer application is to display albums retrieved from a REST call. To handle this task, a new user control, named AlbumControl, was added into a UserControls folder within the project. The AlbumControl file is used to display a single album in the carousel and contains the XAML (see Figure 7) to display album covers and show a reflection.
Looking through the XAML in Figure 7, you'll see several data-binding expressions that handle binding images and height and width values. The properties that the different XAML attributes are bound to are exposed by an object called AlbumData, which holds positioning and image information for each album.
Figure 8 shows the AlbumData class. The AlbumData object is assigned to the user control's DataContext so that controls within the user control can bind to the appropriate properties. It's important to note that Windows Phone 7 data bindings are defined just like you'd see in a regular Silverlight application. This really breaks down the learning curve if you already work with Silverlight and are used to binding controls to object properties.
The code-behind class for the AlbumControl user control accepts an AlbumData object in its constructor and assigns it to the DataContext in the Loaded event handler. It also handles creating an ImageBrush from a URI returned from Amazon.com in order to display the album image. The constructor, Loaded event handler, and additional helper methods defined in AlbumControl are shown in Figure 9.
Walking through the code in Figure 9, you can see that the AlbumData object passed to the code-behind constructor is assigned to a field named _AlbumData. From there, the code creates an ImageBrush object within the CreateImageBrush method that is based on the URI of the image returned from a call to the Amazon REST service. The ImageBrush object is assigned to the AlbumData object's ImageBrush property so that the appropriate image is displayed in the application. Although the remainder of the code won't be shown here, the sample project available with this article contains everything you'll need to see how users can interact with an album once it's rendered.
Retrieving Album Data from Amazon
Now that you've seen how each album is rendered, let's discuss how data is retrieved from Amazon's REST service and displayed in the Windows Phone 7 application. After creating the AlbumControl user control, I added another user control named AlbumsContainer into the UserControls folder and referenced it in MainPage.xaml as shown next:
AlbumsContainer is responsible for handling user input and arranging the individual album user controls to simulate the 3D carousel. It contains data loading functionality that handles displaying an animated image to the user as a search is performed. It also contains the TextBox and Button controls used to search, a Canvas that acts as the container for the different album images, an album navigation section with arrow images, and a section to display album details (refer back to Figure 3). Although I won't show the complete XAML file here, it's available in the sample project.
To retrieve album data from the Amazon REST service, a class named AmazonRESTSearch is used. It relies upon the WebClient class (located in the System.Net namespace) to handle sending and retrieving data. Specific values must be passed to the Amazon REST service in order to get back data successfully, and it's important to note that you'll have to get your own keys in order to use the sample. You can create an Amazon Web Services account here. Once you have your keys, update the variables at the bottom of the AmazonRESTSearcher class.
Amazon requires a signed request to be sent, and the sample project includes a class named SignedRequestHelper that simplifies this process. The signed request object creates a URL that can be used to call the service using the WebClient object as shown in Figure 10.
Once the REST service returns data, it's parsed using LINQ to XML and serialized into an Album object array. The Album class contains properties such as Title, Artist, ImageUrlMedium, Reviews, Songs, and more. Once the array is created, it's passed to the AlbumsContainer user control discussed earlier using an event named SearchCompleted. The event handler triggers rendering of the albums in the carousel as shown in Figure 11.
As the user interacts with the navigation controls (arrow images shown in Figure 3), the carousel moves, and albums in the back are moved to the front. As an album comes around to the front, its details, including the album cover, title and price, are shown below the navigation controls. Rotation of the albums in the carousel is controlled using sine and cosine functions handled by a method named MoveAlbums in the AlbumsContainer code-behind class.
Additional Features for the Future
There's still a lot of work I'd like to do on the Windows Phone 7 Album Viewer application, but there's a nice starter foundation in place that can be refactored and enhanced going forward. Although the code runs fine in the emulator, it needs to be optimized for running on a real device. Additional features I'd like to add include an album details screen, support for gestures, refactoring of the code into a more MVVM compliant pattern, tombstoning functionality to store and reload search data if a user leaves the application and comes back to it later, sounds when animations play, integration with the accelerometer for the carousel rotation, and more.
If you have specific ideas or feature suggestions that you'd like to see in upcoming articles, contact me through my blog at weblogs.asp.net/dwahlin or let me know on Twitter using @DanWahlin.
Dan Wahlin is a Microsoft MVP and founded The Wahlin Group, which specializes in ASP.NET MVC, jQuery, Silverlight, and SharePoint consulting and training solutions. Dan has written several books on .NET and writes for several different technical magazines. He blogs at weblogs.asp.net/dwahlin.