Académique Documents
Professionnel Documents
Culture Documents
codeguru
TM
an
Developer eBook
contents
Windows Phone 7 Quick Start Developer Guide
2
2 4
Preface
4 6
Where to Start
15
15 23
Page Navigation
23
35
35
45
45
60
60 68 79
Touch
68
79
86 90
References
86
91
Preface
hen Microsoft announced the Windows Phone 7 Series, its new platform for mobile devices, a big buzz was created. It became a popular topic. A few months later the word Series was dropped because the name was just too long. In September 2010 the final SDK was made available and Microsoft provided free tools to develop applications for the new platform. Todays phones are complex devices incorporating phone, camera, GPS, Wi-Fi, email, sensors and other features. We call them smartphones, and there are lots of these devices on the market. What makes the difference though is not so much the hardware, but the software. Applications sell smartphones, and Microsoft probably understood that they would be successful only if they quickly got a large application base for its users to choose from. So they made their development tools available for free. At the time of writing this eBook the marketplace had over 7,000 applications and it was estimated that by March 2011 that number will increase to over 10,000. If you have already developed for other mobile platforms you probably dont want to ignore this one. Or maybe you havent developed for mobile devices yet but would like to start with the Windows Phone. This eBook is for you. It is a quick start for developing Windows Phone applications in Silverlight. Developers can create applications for Windows Phone 7 using either Silverlight or the XNA frameworks. This eBook covers only Silverlight and includes topics such as page navigation, use of application toolbar, application lifecycle and data persistence, special controls such as pivot, panorama and Bing Maps, special APIs that enable common tasks such as making phone calls, sending e-mails or taking pictures, handling of touch input and others. Readers will probably want to refer to additional readings to complete their study of Windows Phone 7 development, as many other topics arent included here, although it is a great start. 2
Back to Contents
Development Tools
To be able to develop for the Windows Phone you need the Windows Phone 7 Developer Tools available to download for free at http://create.msdn.com/. The package includes the following tools: Microsoft Visual Studio 2010 Express for Windows Phone, Express Blend
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
4 for Windows Phone, Silverlight for Windows Phone, XNA Game Studio for Windows Phone 7, Windows Phone Emulator and Phone Registration Tool. If you already have Microsoft Visual Studio 2010 (any edition) the Express edition will not be installed, the setup will only add the necessary support (such as project templates) to develop for Windows Phone 7 to your installed IDE. In January 2011, while this eBook was a work in progress, Microsoft released an update to the developer tools. This update allows developers to build applications with updated assemblies that will ship in the forthcoming Windows Phone OS update (date is unknown). The update includes support for copy and paste, improved app performance, several minor bug fixes and other enhancements. In addition you might find helpful to use the Silverlight for Windows Phone 7 Toolkit available for download at http:// silverlight.codeplex.com/. It contains richer controls that you can incorporate into your applications and a higherlevel support for touch, which will be addressed in a chapter in this eBook. All the examples presented in this eBook (and the accompanying source code) can be ran and tested with the emulator. The emulator is basically a virtual machine running the same operating system as the physical devices so your applications should behave identically under the emulator or the real device. Differences can appear in regard to touch gestures. The emulator transforms mouse clicks into touch events, but only supports touch with one finger. You can get multi-touch events with the emulator if you have a multi-touch monitor and youre running Windows 7. Otherwise you need a real device for multi-touch testing. Eventually youll have to deploy your applications to a real device. You need to follow several steps before you can do that. First you need to register as a developer at AppHub (http://create.msdn.com/) and enroll your device. Then you must use the Phone Registration Tool (while also running the Zune software on the PC) to enable development for the device. After that you can deploy 3
Back to Contents
application to the Windows Phone device. The submission process will make the topic of the last chapter.
Code Samples
This eBook is accompanied by a ZIP archive with source code for the applications described and developed throughout the eBook. In some cases we give detailed description and source code within the text so that you can reproduce these applications for yourself. In other cases some parts (usually not very important for the discussed topic) are left out so youll need the source code to follow them entirely. All the samples have been ran and verified with the Windows Phone emulator. All the code samples presented throughout the chapters of this eBook are in XAML and C#. However, it is possible to develop for the Windows Phone either in C# (with any edition of Visual Studio 2010) or VB.NET (with the later only if you have Visual Studio 2010 Professional edition or higher). You dont need to be an expert in Silverlight to be able to create applications for the Windows Phone. The topics are presented throughout the eBook in a manner that will allow you to acquire new skills progressively. At the end of the eBook you will be familiar with some of the most important topics. However, youll need additional resources to truly master Silverlight for Windows Phone.
Feedback
Though the authors and the reviewers tried to eliminate any error it is possible that some have occurred. Should you find any error please send an e-mail at submit@ codeguru.com.
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Chapter 1
Where to Start
he announcement on October 11, 2010 from Microsoft about its Windows Phone launch came as no surprise to the mobile community. Ever since Apple launched the iPhone in 2007, the mobile arena has seen a Botox like face-lift. In the hardware front, keyboard-less phones have started to push out the QWERTY keyboard phones as uncool and obsolete, while, at the same time, the Appstore has delighted consumers and applications of all sorts are available on the iPhone and the story is repeating with the Android platform. Realizing that it missed the boat with the Windows Mobile story, Microsoft did a reset on its mobile efforts and came up with a new platform with a modern UI and a robust programming model.
7 platform. The framework provides a lot of managed APIs for game development. Both these frameworks run atop the Common Base Class Library thus ensuring that your C# or VB.NET programming skills can be reused for Windows Phone 7 application development. This eBook is solely about Silverlight. Silverlight for Windows Phone is a modified version of Silverlight 3, with some features removed, and some, specific to the phone, added into the platform.
Development Tools
Before we can start developing for the Windows Phone, well need to download and install the appropriate development tools. The set of tools is known as Windows Phone 7 Developer Tools and are available for free at http://create.msdn.com/ (or directly at the following URL http://go.microsoft.com/ fwlink/?LinkId=185584). The following will be installed: Visual Studio 2010 Express for Windows Phone, the IDE for application development for Windows Phone Express Blend 4 for Windows Phone, WYSIWYG designer for XAML-based interfaces for Silverlight applications Silverlight for Windows Phone 7, for XAML based application development XNA Game Studio for Windows Phone 7, for game development
Platform Overview
The Windows Phone Runtime is a sandboxed environment where managed code can execute in a safe and secure environment. The sandbox ensures that one rogue application cannot impact the other applications in a detrimental way. The Runtime supports two frameworks to build applications on: Silverlight for Windows Phone: Silverlight is an ideal platform for Rich Internet Applications, as was very evident from the online streaming videos of Olympics 2008. XNA Framework: This is ideal for game development framework for Xbox 360, Zune and the Windows Phone 4
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Installation
Clicking on the link above downloads vm_setup.exe which is the web installer for the developer tools. Once you launch it and navigate through the installation steps, it takes about 30 minutes to complete the installation. If you have retail version of Microsoft Visual Studio installed (not the Express SKUs), the installer will install the templates for the Windows Phone 7 development so that you can use them from the Microsoft Visual Studio 2010 installation itself, without the need to use the Visual Studio 2010 Express for Windows Phone 7.
App Hub
The erstwhile Windows Phone 7 marketplace has been reincarnated as the App Hub (http://create.msdn.com). While the tools for developing applications for Windows Phone are free, getting the application approved for the marketplace and selling them requires paying an annual $99 fee. Currently this fee allows you to publish any number of paid applications, but you are limited to 5 free applications. You have to pay for publishing additional free applications.
Installation Requirements
To install the Windows Phone 7 developer tools, you will need the following: Operating system: Windows Vista or Windows 7 - All editions except Starter Editions Disk space: 3 GB RAM: 2 GB For the emulator to work, you will need a DirectX 10 capable graphics card
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Chapter 2
Having installed the Windows Phone 7 Developer Tools you are ready to start writing WP7 applications. If you open Visual Studio 2010 youll see several templates under the category Silverlight for Windows Phone. The one well use in this chapter is the first one, simply called Windows Phone Application. Well call this first application WP7HelloWorld. This application will display a list of available languages and when selecting one language, the application will greet us with hello world in that language. The following image shows the available templates for Silverlight for Windows Phone.
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
There are two XAML files, one App.xaml for the Application class, and the other MainPage.xaml for the main page of your application. In addition there are several images including an application icon (though all of them are PNGs). If you open the MainPage.xaml youll see the page in the design pane.
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
FontFamily={StaticResource PhoneFontFamilyNormal} FontSize={StaticResource PhoneFontSizeNormal} Foreground={StaticResource PhoneForegroundBrush} SupportedOrientations=Portrait Orientation=Portrait shell:SystemTray.IsVisible=True> <!--LayoutRoot is the root grid where all page content is placed--> <Grid x:Name=LayoutRoot Background=Transparent> <Grid.RowDefinitions> <RowDefinition Height=Auto/> <RowDefinition Height=*/> </Grid.RowDefinitions> <!--TitlePanel contains the name of the application and page title--> <StackPanel x:Name=TitlePanel Grid.Row=0 Margin=12,17,0,28> <TextBlock x:Name=ApplicationTitle Text=MY APPLICATION Style={StaticResource PhoneTextNormalStyle}/> <TextBlock x:Name=PageTitle Text=page name Margin=9,-7,0,0 Style={StaticResource PhoneTextTitle1Style}/> </StackPanel> <!--ContentPanel - place additional content here--> <Grid x:Name=ContentPanel Grid.Row=1 Margin=12,0,12,0></Grid> </Grid> <!--Sample code showing usage of ApplicationBar--> <!--<phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar IsVisible=True IsMenuEnabled=True> <shell:ApplicationBarIconButton IconUri=/Images/appbar_button1.png Text=Button 1/> <shell:ApplicationBarIconButton IconUri=/Images/appbar_button2.png Text=Button 2/> <shell:ApplicationBar.MenuItems> <shell:ApplicationBarMenuItem Text=MenuItem 1/> <shell:ApplicationBarMenuItem Text=MenuItem 2/> </shell:ApplicationBar.MenuItems> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar>--> </phone:PhoneApplicationPage>
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
The translations for the hello world text are stored in a dictionary, whose key is the language (if I got the translations wrongs, it is Google Translators fault). When the user selects a new item, the handler LanguageList_SelectionChanged is called and the page title is updated.
public partial class MainPage : PhoneApplicationPage { Dictionary<string, string> greetings; // Constructor public MainPage() { InitializeComponent(); greetings = new Dictionary<string, string>(); greetings[English] = Hello world;
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
greetings[French] = Bonjour tout le monde; greetings[German] = Hallo Welt; greetings[Spanish] = Hola mundo; greetings[Portuguese] = Ol mundo mundo; greetings[Italian] = Ciao a tuti; greetings[Romanian] = Salutare lume; LanguageList.ItemsSource = greetings.Keys; } private void LanguageList_SelectionChanged(object sender, SelectionChangedEventArgs e) { PageTitle.Text = greetings[LanguageList.SelectedItem as string]; } }
After deployment, the application will automatically show up in the emulated phone. The image below shows the application at startup and after the user selected Spanish in the list.
10
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Note: For more styles, such as PhoneTextExtraLargeStyle see Theme Resource for Windows Phone in MSDN. Second, well create an INotifyPropertyChanged implementation that will represent the items of the list box. public class LanguageItemViewModel : INotifyPropertyChanged
{ private string _Language; public string Language { get { return _Language; } set { if (value != _Language) { _Language = value; NotifyPropertyChanged(Language);
11
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
} } } private BitmapImage _image; public BitmapImage Icon { get { return _image; } set { if (value != _image) { _image = value; NotifyPropertyChanged(Icon); } } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (null != handler) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }
Third, well have to change the item source for the list elements. It used to be the collection of keys in the dictionary, but now it will look like this:
LanguageList.ItemsSource = from g in greetings.Keys select new LanguageItemViewModel { Icon = new BitmapImage( new Uri(String.Format(Images\\{0}.png, g), UriKind.Relative)),
12
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Language = g };
Fourth, then handler for the selection change must be updated, but the change is quite simple. private void LanguageList_SelectionChanged(object sender, SelectionChangedEventArgs e) { LanguageItemViewModel item = LanguageList.SelectedItem as LanguageItemViewModel; if(item != null) { PageTitle.Text = greetings[item.Language]; } }
And last, we need images for the flags, stored under the Images folder in the project root (otherwise you have to change the Uri of the BitmapImages created in the constructor of the main page). After all these changes the project structure will be:
13
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Summary
This chapter was an introduction to developing Silverlight for Windows Phone projects. We have seen how to create a new project and how to use the designer to browse and modify the content of the page (in XAML). We took a short look at the major elements of a page and we added a list box to the content panel. Later we customized the list by modifying its default data template and populated it with elements that have both an image and a text.
14
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Chapter 3
15
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
If you remove the comment the app bar will show up in designer, however the visualization is rather a static image than the actual bar you get at runtime, and shows four circles representing the buttons (even if you define less than four buttons). The following image shows on the left how the page looks in the designer and on the right how it looks at runtime when you click on the app bar to show it entirely.
Using Images
Microsoft provides a set of several simple images in two versions (light and dark) that you can use in your application. Of course, you can create and use your own, except that you should follow the recommendation for the size and aspect. When you install the WP7 Developer Tools you get these icons installed in the folder Program Files\Microsoft SDKs\ Windows Phone\V7.0\Icons.
16
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
In this example I will use appbar. add.rest.png for an Add button and appbar.delete.rest.png for a Delete button, and change the application bar to the following definition (given that these images were copied to a folder called Images in the application folder):
<shell:ApplicationBarIconButton IconUri=/Images/appbar.add.rest.png Text=Add/> <shell:ApplicationBarIconButton IconUri=/Images/appbar.delete.rest.png Text=Delete/> <shell:ApplicationBar.MenuItems> <shell:ApplicationBarMenuItem Text=Delete all/> </shell:ApplicationBar.MenuItems>
However, if you run the application now in the emulator you wont see the specified images, but a default image. Reason is that when you add the images to the project they are flagged as Resource. You should go to the properties of the images and change the Build Action property to Content, as shown in the following image. After that, the images will be correctly packaged and deployed to the phone, so that the app bar will correctly display them.
17
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Building an Example
To see the app bar at work well create a simple example: the main content of the page will be a list with the items being plain strings. The app bar will have two buttons: one called add that when pressed will add a new item to the list, and one called delete. When pressed, it will enable the delete mode for the application, meaning that when taping on a list item, that item will be removed from the list. When pressed again, the delete button will end the delete mode, so selecting the list items will no longer remove them. Also, the app bar will have a menu item called delete all that when pressed will remove all the items from the list. The definition for this app bar was already shown in the previous paragraph. The following code shows the definition with handlers for the Click event for each button and menu item.
<phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar IsVisible=True IsMenuEnabled=True> <shell:ApplicationBarIconButton x:Name=btnAdd IconUri=Images/appbar.add.rest.png Text=Add Click=btnAdd_Click /> <shell:ApplicationBarIconButton x:Name=btnDel IconUri=Images/appbar.delete.rest.png Text=Delete
18
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Click=btnDel_Click/> <shell:ApplicationBar.MenuItems> <shell:ApplicationBarMenuItem x:Name=menuDelAll Text=Delete all Click=menuDelAll_Click/> </shell:ApplicationBar.MenuItems> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar>
Also, the content panel with the list box is defined as:
<!--ContentPanel - place additional content here--> <Grid x:Name=ContentPanel Grid.Row=1 Margin=12,0,12,0> <ListBox x:Name=ListContent Grid.Row=0 SelectionChanged=ListContent_SelectionChanged /> </Grid>
Using x:Name
You cant use the x:Name for the buttons and menu items. Though you can set the values in the XAML code, trying to access the elements from .NET code will fail, because these objects will always be null. The following code is incorrect.
btnAdd.IsEnabled = false; menuDelAll.IsEnabled = false;
Instead you should use the Buttons and MenuItems properties of ApplicationBar (both of type IList) and get references to the actual controls. The code should look like this:
ApplicationBarIconButton m_appbarBtnAdd; ApplicationBarIconButton m_appbarBtnDel; ApplicationBarMenuItem m_appbarMenuDelAll; public MainPage() { InitializeComponent(); m_appbarBtnAdd = ApplicationBar.Buttons[0] as ApplicationBarIconButton; m_appbarBtnDel = ApplicationBar.Buttons[1] as ApplicationBarIconButton; m_appbarMenuDelAll = ApplicationBar.MenuItems[0] as ApplicationBarMenuItem; }
19
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
The following image shows the difference between disabling only the menu item (left) or disabling the entire menu (right).
// disable only the menu item m_appbarMenuDelAll.IsEnabled = false; // disable the entire menu of the app bar ApplicationBar.IsMenuEnabled = false;
20
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
21
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
{ ListContent.Items.Clear(); } private void ListContent_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (m_deleting) { object sel = ListContent.SelectedItem; if (sel != null) ListContent.Items.Remove(sel); } } }
Summary
The app bar is a control meant to hold several buttons and menu items for common or most used commands. It is not a customizable control and is not actually part of the visual tree of the page. Each page has its own app bar and you can show and hide, enable and disable it entirely or its controls individually. In this chapter weve seen: how the wizards adds a default app bar to the page, but keeps the definition commented what elements the application bar has what restrictions are imposed on the application bar how images can be used with the application bar how to handle events for the application bar buttons and menu items
22
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Chapter 4
Page Navigation
n the previous two chapters we have seen how to create a simple WP7 Silverlight application and how to use the app bar to expose common commands. The demo applications weve seen so far had only one page. However, it is likely that any serious application will probably require more than just one page. This chapter will focus on page navigation and passing data between pages. In this chapter you will learn how to: add additional pages to a Silverlight application for WP7 navigate to a new page navigate backwards to an already opened page pass data to a new page with the query string pass data between pages with the transient storage
23
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
The button has a handler for the Click event, and in the handler well navigate to the settings page. Well get into the details in the next paragraph.
private void btnSettings_Click(object sender, EventArgs e) { this.NavigationService.Navigate(new Uri(/SettingsPage.xaml, UriKind.Relative)); }
The settings page will have a group of radio buttons representing available colors for the mains page grid background. The content panel in this page will look like this (for the moment):
<!--ContentPanel - place additional content here--> <Grid x:Name=ContentPanel Grid.Row=1 Margin=12,0,12,0> <StackPanel> <RadioButton Content=Black /> <RadioButton Content=White /> <RadioButton Content=Red /> <RadioButton Content=Yellow /> <RadioButton Content=Blue /> <RadioButton Content=Green /> </StackPanel> </Grid>
24
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
To navigate back we have to handle the Click event and use the navigation service to navigate back.
private void btnSelect_Click(object sender, EventArgs e) { this.NavigationService.GoBack(); }
This is how the two pages of the application will look at this point.
25
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Then Ill create a value converter to convert from this enumerator to bool and the other way around.
public class EnumBoolConverter : IValueConverter {
26
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null || parameter == null) return value; return value.ToString() == parameter.ToString(); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null || parameter == null) return value; return Enum.Parse(targetType, (String)parameter, true); } }
An implementation of INotifyPropertyChange will be used for the binding mechanism. This view model will be the data context for the settings page.
public class ColorOptionViewModel : INotifyPropertyChanged { private ColorOption _userOption; public ColorOption UserOption { get { return _userOption; } set { if (_userOption != value) { _userOption = value; RaisePropertyChanged(UserOption); } } } public virtual void RaisePropertyChanged(string propertyName) {
27
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
} Then, in the XAML code of the second page, well have to add two things: first, the enum-to-bool converter as a static resource in the page:
<phone:PhoneApplicationPage.Resources> <local:EnumBoolConverter x:Key=ConvertEnum /> </phone:PhoneApplicationPage.Resources>
Second, well alter the definition of the radio buttons to look like this:
<StackPanel> <RadioButton Content=Black IsChecked={Binding Path=UserOption, Mode=TwoWay, Converter={StaticResource ConvertEnum}, ConverterParameter=Black} /> <RadioButton Content=White IsChecked={Binding Path=UserOption, Mode=TwoWay, Converter={StaticResource ConvertEnum}, ConverterParameter=White} /> <RadioButton Content=Red IsChecked={Binding Path=UserOption, Mode=TwoWay, Converter={StaticResource ConvertEnum}, ConverterParameter=Red} /> <RadioButton Content=Yellow IsChecked={Binding Path=UserOption, Mode=TwoWay, Converter={StaticResource ConvertEnum}, ConverterParameter=Yellow} /> <RadioButton Content=Blue IsChecked={Binding Path=UserOption, Mode=TwoWay, Converter={StaticResource ConvertEnum}, ConverterParameter=Blue} /> <RadioButton Content=Green IsChecked={Binding Path=UserOption, Mode=TwoWay, Converter={StaticResource ConvertEnum}, ConverterParameter=Green} /> </StackPanel>
Now, well be able to use ColorOptionViewModel as data context for the page and do the following:
// in the constructor this.DataContext = new ColorOptionViewModel();
28
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
The radio button corresponding to the specified color will be selected automatically.
The Uri string will look like /SettingsPage.xaml?Color=1. The page that is navigated to will be able to query for these values using the NavigationContext property of the Page class. The following example shows how to do it.
protected override void OnNavigatedTo(NavigationEventArgs e) { IDictionary<string, string> parameters = this.NavigationContext.QueryString; if (parameters.ContainsKey(Color)) { int colorindex; int.TryParse(parameters[Color], out colorindex); // do something with the value } base.OnNavigatedTo(e); }
Method OnNavigatedTo is called by the framework after the page is created and before it is displayed, to allow you to examine the navigation request (the arguments passed through the query string) and prepare the page for display. This method is called for each request, even when the page is retrieved from the cache. So if you have code that must be executed for each request it should be placed here, not in the constructor. There are also two method called OnNavigatingFrom and OnNavigatedFrom. The first is called just before a page becomes inactive, while the second is called after the page has become inactive. 29
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Notice that in the MainPage we handle the Loaded event, and set the appropriate brush for the grid background, based on the user selection stored in the m_option variable. On the other hand, in the OnNavigatedTo method of the SettingsPage, after reading the value from the query string we set it to the UserOption property of the view model that represents the DataContext. Due to the bindings we put earlier in the XAML code, the appropriate radio button will be selected.
30
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
public partial class SettingsPage : PhoneApplicationPage { public SettingsPage() { InitializeComponent(); this.DataContext = new ColorOptionViewModel(); } private void btnSelect_Click(object sender, EventArgs e) { this.NavigationService.GoBack(); } protected override void OnNavigatedTo(NavigationEventArgs e) { IDictionary<string, string> parameters = this.NavigationContext.QueryString; if (parameters.ContainsKey(Color)) { int colorindex; int.TryParse(parameters[Color], out colorindex); (DataContext as ColorOptionViewModel).UserOption = (ColorOption)colorindex; } base.OnNavigatedTo(e); } }
Suppose initially the selected color was green (as seen in the mains page constructor), the selected radio button when loading the settings page will be the last one, representing Green. As stated earlier in this paragraph, this method has an important drawback: its only one way. We cannot pass parameters with the GoBack method when navigating to the previous page on the stack. This method does not take an Uri, so we cannot provide a query string. We cannot call Navigate either, because that would create a new instance of the main page. So we need an alternative way for passing data between pages.
31
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
PhoneApplicationService is a class that provides access to aspects of the applications lifetime, including the management of the idle behavior and the applications state when it becomes active or inactive. One of its members is a property called State, which is a dictionary of object values with string as the key type. This dictionary can be used for storing transient data, i.e. data available only while the application is running. You cannot store data that must be available between different executions of the application. Well discuss about that in a next chapter. One requirement for the objects stored in this dictionary is that they are serializable. We can do the following to pass the color between the main page and settings page: In the Click handler for the Settings button in the main page, put the current color in the State dictionary In the OnNavigatedTo method of the settings page, extract the value from the dictionary and set it in the view model representing the DataContext To pass the new value back from the settings page to the main page we have to do these steps: In the Click handler for the Select button of the settings page app bar, put the selected color in the State dictionary In the OnNavigatedTo method of the main page, extract the color from the dictionary and store it in the m_option variable (that weve seen earlier). The new code for the two pages will be:
public partial class MainPage : PhoneApplicationPage { ColorOption m_option; public MainPage() { InitializeComponent(); m_option = ColorOption.Green; }
32
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
private void btnSettings_Click(object sender, EventArgs e) { PhoneApplicationService.Current.State[Color] = m_option; this.NavigationService.Navigate( new Uri(/SettingsPage.xaml, UriKind.Relative)); } protected override void OnNavigatedTo(NavigationEventArgs e) { object obj; if (PhoneApplicationService.Current.State.TryGetValue(Color, out obj)) { m_option = (ColorOption)obj; } base.OnNavigatedTo(e); } private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e) { Color color = Colors.Black; switch(m_option) { case ColorOption.Black: color = Colors.Black; break; case ColorOption.White: color = Colors.White; break; case ColorOption.Red: color = Colors.Red; break; case ColorOption.Yellow: color = Colors.Yellow; break; case ColorOption.Blue: color = Colors.Blue; break; case ColorOption.Green: color = Colors.Green; break; } ContentPanel.Background = new SolidColorBrush(color); } }
public partial class SettingsPage : PhoneApplicationPage { public SettingsPage() { InitializeComponent(); this.DataContext = new ColorOptionViewModel(); }
33
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
private void btnSelect_Click(object sender, EventArgs e) { PhoneApplicationService.Current.State[Color] = (DataContext as ColorOptionViewModel).UserOption; this.NavigationService.GoBack(); } protected override void OnNavigatedTo(NavigationEventArgs e) { object obj; if (PhoneApplicationService.Current.State.TryGetValue(Color, out obj)) { (DataContext as ColorOptionViewModel).UserOption = (ColorOption)obj; } base.OnNavigatedTo(e); } }
Now, when we run the application, after selecting a color and pressing the Select button in the settings page, the application will navigate back to the main page and the background color of the grid will change to the selected color. The following image shows how it works.
Summary
Real WP7 Silverlight applications will probably require more than just one page. We can navigate between them using the NavigationService property of a page. The pages are stacked in the order of navigation and this service allows you to navigate back and forward through the stack. Passing data between pages is possible in several ways. In this chapter weve seen how to use the query string of an Uri to pass data to a new page, and the applications State dictionary to pass data between any pages.
34
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Chapter 5
Tombstoning
On Windows Phone 7 only one application can run at a time, as the system does not support multi-tasking. The reason is that multiple applications running on the background can degrade the performance. On the other hand, users can navigate forward or backwards through the stack of (previously) running applications; forward, by starting applications from the installed applications list or from a tile on Start, and backwards using the Back button.
the calling application). Launchers and choosers will be discussed later in the eBook. When the user presses the Back button, the application is terminated. However, when the user presses the Start button, or a launcher or chooser starts, the application is not terminated, but put into a sort of hibernation, with the system maintaining application state; if the user returns to the application by pressing the Back button, or when the launcher or chooser terminates, the application is resurrected and the application state restored. This process is called tombstoning. The image below shows (in green) the possible states of the application and the events fired when the state changes (in red).
In addition, applications can be interrupted by launchers (APIs that WP applications can use to enable tasks such as making phone calls or sending emails, without returning any data to the calling application) or choosers (APIs that WP applications can use to launch built-in application that allows the user to complete a task, such as taking a picture, which returns some data to
35
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
(shown in red rectangles in the previous image): Launching: occurs when the application is being launched. Closing: occurs when the application is terminated as a result of pressing the Back button on the first page. Activated: occurs when the application is made active after being previously tombstoned, as a result of returning to the application with the Back button or a launcher/chooser finishing work. Deactivated: occurs when the application is tombstoned as a result of pressing the Start button or a launcher/chooser activating.
Preserving State
The data associated with an application can be grouped in two categories: Transient: data that is reinitialized each time the application starts, but needs to be preserved when the application is tombstoned
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Building an example
To show how to manage the application lifecycle and application settings well build an example that backs-up and restores both page state and application state. This Silverlight application will have one single page that displays three counters: total starts of the applications (persistent application state) total re-activations of the application from tombstoning after the last fresh start-up (transient application state) total hits of a button on the main page (transient page state) This is how the XAML code for the content panel of the main page should look like:
<!--ContentPanel - place additional content here--> <Grid x:Name=ContentPanel Grid.Row=1 Margin=12,0,12,0> <StackPanel Grid.Row=0> <TextBlock Text=Total application runs HorizontalAlignment=Center TextAlignment=Center Style={StaticResource PhoneTextTitle2Style}/> <TextBlock x:Name=totalAppRuns Text=0 HorizontalAlignment=Center Style={StaticResource PhoneTextTitle1Style} /> <TextBlock Text=Total application activations since last start TextWrapping=Wrap HorizontalAlignment=Center TextAlignment=Center Style={StaticResource PhoneTextTitle2Style}/>
37
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
<TextBlock x:Name=totalAppActivations Text=0 HorizontalAlignment=Center Style={StaticResource PhoneTextTitle1Style} /> <TextBlock Text=Total button hits since the last start TextWrapping=Wrap HorizontalAlignment=Center TextAlignment=Center Style={StaticResource PhoneTextTitle2Style}/> <TextBlock x:Name=totalButtonHits Text=0 HorizontalAlignment=Center Style={StaticResource PhoneTextTitle1Style} /> <Button x:Name=btnHit Content=Hit me Click=btnHit_Click/> </StackPanel> </Grid>
38
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
39
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
<Application.ApplicationLifetimeObjects> <!--Required object that handles lifetime events for the application--> <shell:PhoneApplicationService Launching=Application_Launching Closing=Application_Closing Activated=Application_Activated Deactivated=Application_Deactivated/> </Application.ApplicationLifetimeObjects>
They are implemented as empty methods in the App class, with comments indicating when the handlers are called. // Code to execute when the application is launching (eg, from Start) // This code will not execute when the application is reactivated private void Application_Launching(object sender, LaunchingEventArgs e) { } // Code to execute when the application is activated (brought to foreground) // This code will not execute when the application is first launched private void Application_Activated(object sender, ActivatedEventArgs e) { } // Code to execute when the application is deactivated (sent to background) // This code will not execute when the application is closing private void Application_Deactivated(object sender, DeactivatedEventArgs e) { } // Code to execute when the application is closing (eg, user hit Back) // This code will not execute when the application is deactivated private void Application_Closing(object sender, ClosingEventArgs e) { } Because you cant be sure that a tombstoned application will actually be re-activated, when the application is deactivating you should store both transient and persistent data and reload it appropriately when activating. You should adhere to the following pattern for saving and loading application data:
40
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Well have two methods for saving and two for loading application data, one pair for the persistent data and one for the transient data. The persistent data is the total number of runs of the application, and the transient data is the total number of activations since the last run. These four methods will look like this (they should be self-explanatory by now):
private void SaveTransientData() { PhoneApplicationService.Current.State[totalActivations] = TotalActivations; } private void LoadTransientData() { object obj; if (PhoneApplicationService.Current.State.TryGetValue(totalActivations, out obj)) { TotalActivations = (int)obj; } } private void SavePersistantData() { if (IsolatedStorageSettings.ApplicationSettings.Contains(totalRuns)) { IsolatedStorageSettings.ApplicationSettings[totalRuns] = TotalRuns; } else { IsolatedStorageSettings.ApplicationSettings.Add(totalRuns, TotalRuns); }
41
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
// make sure data is saved immediately IsolatedStorageSettings.ApplicationSettings.Save(); } private void LoadPersistantData() { if (IsolatedStorageSettings.ApplicationSettings.Contains(totalRuns)) { TotalRuns = (int)IsolatedStorageSettings.ApplicationSettings[totalRuns]; } }
Following the pattern described earlier will call them from the proper event handlers:
// Code to execute when the application is launching (eg, from Start) // This code will not execute when the application is reactivated private void Application_Launching(object sender, LaunchingEventArgs e) { LoadPersistantData(); TotalRuns++; } // Code to execute when the application is activated (brought to foreground) // This code will not execute when the application is first launched private void Application_Activated(object sender, ActivatedEventArgs e) { LoadPersistantData(); LoadTransientData(); TotalActivations++; } // Code to execute when the application is deactivated (sent to background) // This code will not execute when the application is closing private void Application_Deactivated(object sender, DeactivatedEventArgs e) { SavePersistantData(); SaveTransientData(); } // Code to execute when the application is closing (eg, user hit Back) // This code will not execute when the application is deactivated private void Application_Closing(object sender, ClosingEventArgs e) {
42
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
SavePersistantData(); } Notice that the total runs counter is only incremented in the handler for the Launching event after loading the persisting data, and the total activations counter is only incremented in the handler for the Activated event after loading the transient data. In order to display these counters in the main page, well need the following addition to the OnNavigatedTo method of the main page (the only page of the application): // application settings App app = Application.Current as App; totalAppActivations.Text = app.TotalActivations.ToString(); totalAppRuns.Text = app.TotalRuns.ToString();
Examples
The first set of images below shows: The counters after starting the application the first time: runs=1, activations=0, button hits=0 The counters after pressing the button three times: runs=1, activations=0, button hits=3 The counters after pressing the Start button to tombstone the application and then the Back button to return to it and activated it: runs=1, activations=1, button hits=3
43
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
The second set of images below shows: The counters after pressing the button two more times: runs=1, activations=1, button hits=5 The counters after pressing the Start button to tombstone the application and then the Back button to return to it and activated it: runs=1, activations=2, button hits=3 The counters after pressing the Back button to close the application and then launching the application again: runs=2, activations=0, button hits=0
Summary
Windows Phone applications can be in different states: they can be activated and reactivated by the system as the user navigates to or from the application, or launchers or choosers start. The application data (whether at page level or application level) should be backed-up and restored. The framework provides different storages for preserving transient and persisting data, and in this chapter we looked at PhoneApplicationService.Current.State (a dictionary for transient data) and IsolatedStorageSettings.ApplicationSettings (a dictionary for persistent data). However, developers can employ other methods for saving application data. In this chapter we created an application that preserved both transient and persistent data, both at page level and application level. We have seen what events should be handled or what methods overridden to save and load data when the application transits from one state to another.
44
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Chapter 6
the same name. They are similar controls allowing you to organize the visual content of your page into smaller parts (subpages or columns), which you can navigate through by sweeping the finger on the screen. Basically pivot and panorama are like a tab control for desktop applications. Each subpage, called item (pivot item or panorama item) has a header and you can also navigate through the items by taping on the header. Both look like a big sheet or canvas grouped into subpages, and you have a view port into one of the subpages at a given time. Pivot and panorama differ in the way the control title and the headers look and how the transition from one item to another occurs, the transition being smoother with panorama.
Overview
These two controls are available in the Microsoft. Phone.Controls namespace from the assembly with
45
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
On the other hand, the pivot, shown in the following image from the same Microsoft document, has a much smaller title, leaving more space for the content of each item. Header items are similar to panorama header items. Using one or the other requires the same development effort and in fact is very easy to switch between the two controls as we will see in this chapter. You can read the guidelines paper for more information and suggestions for the two controls.
Demo Application
In this chapter well create a simple application that will show how to use the pivot and panorama controls and what the differences between the two are. This application will have a main page with a text block that allows us to enter the title of a movie, a Search button to search the movie in the IMDB database and two radio buttons that specify in which format the results should be displayed, pivot or panorama. Both controls will have four items: overview, with several information about the movie such as release date, plot, main actors, list directors and writers synopsis, listing the summary of the movie cast, displaying a list of the actors poster, containing the main poster for the movie (as listed in the IMDB database) The following image shows the main page and the first item of the pivot control displaying results for the Gladiator movie.
46
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Note: IMDB does not provide a service to query its database. To retrieve information about a movie I used a modified version of an ASP.NET scrapper API implemented by Abhinay Rathore and available on his blog at http://web3o. blogspot.com. What it does is performing a Google search for a movie title with the Im Feeling Lucky option, which automatically directs the result to the IMDB website. The returned HTML page is then parsed with regular expressions to extract data from it. Not the best possible approach, but better than nothing. And anyways, the point of the chapter is presenting the pivot and panorama controls, and not APIs for fetching movie information.
Using a Pivot
To add a page with a pivot control, use the Add New Item command and from the available pages select Windows Phone Pivot Page. This will add a new page with the layout root containing a pivot (well call this MoviePivotPage.xaml).
The XAML code generated by the wizard for the pivot control looks like this:
<!--LayoutRoot is the root grid where all page content is placed--> <Grid x:Name=LayoutRoot Background=Transparent> <!--Pivot Control--> <controls:Pivot Title=my application> <!--Pivot item one--> <controls:PivotItem Header=item1> <Grid>
47
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
</controls:PivotItem> <!--Pivot item two--> <controls:PivotItem Header=item2> <Grid> </controls:PivotItem> </controls:Pivot> </Grid>
As you can see the wizard defines two pivot items (the class that represents a pivot item is simply called PivotItem), with an empty grid as the content. We can either use the grid to add more controls, or replace it with a stack panel or a list (as well see in this example) or any other control. The following listing shows how the pivot will look in this example, with various controls used to display movie information in each of the four pivot items (overview, synopsis, cast and poster).
<!--LayoutRoot is the root grid where all page content is placed--> <Grid x:Name=LayoutRoot Background=Transparent> <!--Pivot Control--> <controls:Pivot Title={Binding Path=Title}> <!--Pivot item one--> <controls:PivotItem Header=overview> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width=150/> <ColumnDefinition Width=*/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> </Grid.RowDefinitions> <TextBlock Grid.Row=0 Grid.Column=0 Margin=5,5,5,5 Text=Year /> <TextBlock Grid.Row=0 Grid.Column=1 Margin=5,5,5,5
48
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Text={Binding Path=Year} /> <TextBlock Grid.Row=1 Grid.Column=0 Margin=5,5,5,5 Text=Release date /> <TextBlock Grid.Row=1 Grid.Column=1 Margin=5,5,5,5 Text={Binding Path=ReleaseDate} /> <TextBlock Grid.Row=2 Grid.Column=0 Margin=5,5,5,5 Text=Rating /> <TextBlock Grid.Row=2 Grid.Column=1 Margin=5,5,5,5 Text={Binding Path=Rating} /> <TextBlock Grid.Row=3 Grid.Column=0 Margin=5,5,5,5 Text=Runtime /> <TextBlock Grid.Row=3 Grid.Column=1 Margin=5,5,5,5 Text={Binding Path=Runtime} /> <TextBlock Grid.Row=4 Grid.Column=0 Margin=5,5,5,5 Text=Plot /> <TextBlock Grid.Row=4 Grid.Column=1 Margin=5,5,5,5 TextWrapping=Wrap Text={Binding Path=Plot} /> <TextBlock Grid.Row=5 Grid.Column=0 Margin=5,5,5,5 Text=Genre(s) /> <ListBox Grid.Row=5 Grid.Column=1 Margin=5,5,5,5 ItemsSource={Binding} x:Name=listGenres/> <TextBlock Grid.Row=6 Grid.Column=0 Margin=5,5,5,5 Text=Staring /> <ListBox Grid.Row=6 Grid.Column=1
49
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Margin=5,5,5,5 ItemsSource={Binding} x:Name=listStars/> <TextBlock Grid.Row=7 Grid.Column=0 Margin=5,5,5,5 Text=Director(s) /> <ListBox Grid.Row=7 Grid.Column=1 Margin=5,5,5,5 ItemsSource={Binding} x:Name=listDirectors/> <TextBlock Grid.Row=8 Grid.Column=0 Margin=5,5,5,5 Text=Writer(s) /> <ListBox Grid.Row=8 Grid.Column=1 Margin=5,5,5,5 ItemsSource={Binding} x:Name=listWriters/> </Grid> </controls:PivotItem> <!--Pivot item two--> <controls:PivotItem Header=synopsis> <StackPanel> <TextBlock Text=Tagline Style={StaticResource PhoneTextTitle2Style}/> <TextBlock Text={Binding Path=Tagline} TextWrapping=Wrap Margin=10,10,10,10/> <TextBlock Text=Storyline Style={StaticResource PhoneTextTitle2Style}/> <TextBlock Text={Binding Path=Storyline} TextWrapping=Wrap Margin=10,10,10,10/> </StackPanel> </controls:PivotItem> <!--Pivot item three--> <controls:PivotItem Header=cast> <ListBox ItemsSource={Binding}
50
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
x:Name=listCast/> </controls:PivotItem> <!--Pivot item four--> <controls:PivotItem Header=poster> <Image x:Name=imgPoster/> </controls:PivotItem> </controls:Pivot> </Grid>
First step is to create an IMDb object holding information about the searched movie (parsed from the IMDB HTML results page) and pass it to the pivot page. We do that with the transient dictionary as weve seen in a previous chapter.
IMDb movie = new IMDb(response); PhoneApplicationService.Current.State[movie] = movie; if (rbtnPivot.IsChecked.HasValue && rbtnPivot.IsChecked.Value) { this.NavigationService.Navigate(new Uri(/MoviePivotPage.xaml, UriKind.Relative)); }
Then, on the results page, we override the OnNavigatedTo handler, fetch the movie from the transient cache and set it as data context for the page and controls.
protected override void OnNavigatedTo(NavigationEventArgs e) { object obj; if (PhoneApplicationService.Current.State.TryGetValue(movie, out obj)) { IMDb movie = (IMDb)obj; this.DataContext = movie; this.listGenres.DataContext = movie.Genres; this.listStars.DataContext = movie.Stars; this.listDirectors.DataContext = movie.Directors; this.listWriters.DataContext = movie.Writers; this.listCast.DataContext = movie.Cast; this.imgPoster.Source = new BitmapImage( new Uri(movie.Poster, UriKind.Absolute)); } base.OnNavigatedTo(e); }
51
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
The Pivot control defines several events: LoadingPivotItem: gives you the opportunity to dynamically load or change the content of a pivot item before it is displayed. LoadedPivotItem: indicates that an item was completely loaded. UnloadingPivotItem: gives you the opportunity to dynamically load, change or remove the content of a pivot item as it is removed. UnloadedPivotItem: indicates that the pivot item has been completely unloaded from the visual pivot. SelectionChanged: indicates that the currently selected item changed. The following events are fired when we open the pivot page with the overview item first displayed, and then we navigate to the synopsis item: SelectionChanged (overview added) LoadingPivotItem (overview) LoadedPivotItem (overview) UnloadingPivotItem (overview)
52
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Then, the page code will change as shown below. Notice that the image is loaded only the first time the LoadedPivotItem fires for the poster item.
public partial class MoviePivotPage : PhoneApplicationPage { IMDb m_movie; public MoviePivotPage() { InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { object obj; if (PhoneApplicationService.Current.State.TryGetValue(movie, out obj)) { m_movie = (IMDb)obj; this.DataContext = m_movie; this.listGenres.DataContext = m_movie.Genres; this.listStars.DataContext = m_movie.Stars; this.listDirectors.DataContext = m_movie.Directors; this.listWriters.DataContext = m_movie.Writers; this.listCast.DataContext = m_movie.Cast; } base.OnNavigatedTo(e); }
53
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
private void Pivot_LoadedPivotItem(object sender, PivotItemEventArgs e) { string header = e.Item.Header as string; if (header == poster) { if (imgPoster.Source == null) imgPoster.Source = new BitmapImage( new Uri(m_movie.Poster, UriKind.Absolute)); } } }
Using a Panorama
Using a panorama is extremely similar to a pivot. In fact the XAML code is identical if you replace the types Pivot with Panorama and PivotItem with PanoramaItem. We will add a new Windows Phone Panorama Page to the project and call it MoviePanoramaPage.xaml.
54
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
<!--LayoutRoot contains the root grid where all other page content is placed--> <Grid x:Name=LayoutRoot> <controls:Panorama Title=my application> <!--Panorama item one--> <controls:PanoramaItem Header=item1> <Grid/> </controls:PanoramaItem> <!--Panorama item two--> <controls:PanoramaItem Header=item2> <Grid/> </controls:PanoramaItem> </controls:Panorama> </Grid>
We will modify the XAML code to define four panorama items with the same controls we added to the pivot items and the same bindings. The following listing shows the code.
<!--LayoutRoot contains the root grid where all other page content is placed--> <Grid x:Name=LayoutRoot> <controls:Panorama Title={Binding Path=Title}> <!--Panorama item one--> <controls:PanoramaItem Header=overview> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width=150/> <ColumnDefinition Width=*/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto /> <RowDefinition Height=Auto />
55
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
</Grid.RowDefinitions> <TextBlock Grid.Row=0 Grid.Column=0 Margin=5,5,5,5 Text=Year /> <TextBlock Grid.Row=0 Grid.Column=1 Margin=5,5,5,5 Text={Binding Path=Year} /> <TextBlock Grid.Row=1 Grid.Column=0 Margin=5,5,5,5 Text=Release date /> <TextBlock Grid.Row=1 Grid.Column=1 Margin=5,5,5,5 Text={Binding Path=ReleaseDate} /> <TextBlock Grid.Row=2 Grid.Column=0 Margin=5,5,5,5 Text=Rating /> <TextBlock Grid.Row=2 Grid.Column=1 Margin=5,5,5,5 Text={Binding Path=Rating} /> <TextBlock Grid.Row=3 Grid.Column=0 Margin=5,5,5,5 Text=Runtime /> <TextBlock Grid.Row=3 Grid.Column=1 Margin=5,5,5,5 Text={Binding Path=Runtime} /> <TextBlock Grid.Row=4 Grid.Column=0 Margin=5,5,5,5 Text=Plot /> <TextBlock Grid.Row=4 Grid.Column=1 Margin=5,5,5,5 TextWrapping=Wrap Text={Binding Path=Plot} /> <TextBlock Grid.Row=5 Grid.Column=0 Margin=5,5,5,5 Text=Genre(s) /> <ListBox Grid.Row=5 Grid.Column=1 Margin=5,5,5,5 ItemsSource={Binding}
56
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
x:Name=listGenres/> <TextBlock Grid.Row=6 Grid.Column=0 Margin=5,5,5,5 Text=Staring /> <ListBox Grid.Row=6 Grid.Column=1 Margin=5,5,5,5 ItemsSource={Binding} x:Name=listStars/> <TextBlock Grid.Row=7 Grid.Column=0 Margin=5,5,5,5 Text=Director(s) /> <ListBox Grid.Row=7 Grid.Column=1 Margin=5,5,5,5 ItemsSource={Binding} x:Name=listDirectors/> <TextBlock Grid.Row=8 Grid.Column=0 Margin=5,5,5,5 Text=Writer(s) /> <ListBox Grid.Row=8 Grid.Column=1 Margin=5,5,5,5 ItemsSource={Binding} x:Name=listWriters/> </Grid> </controls:PanoramaItem> <!--Panorama item two--> <controls:PanoramaItem Header=synopsis> <StackPanel> <TextBlock Text=Tagline Style={StaticResource PhoneTextTitle2Style}/> <TextBlock Text={Binding Path=Tagline} TextWrapping=Wrap Margin=10,10,10,10/> <TextBlock Text=Storyline Style={StaticResource PhoneTextTitle2Style}/> <TextBlock Text={Binding Path=Storyline} TextWrapping=Wrap Margin=10,10,10,10/>
57
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
</StackPanel> </controls:PanoramaItem> <!--Panorama item three--> <controls:PanoramaItem Header=cast> <ListBox ItemsSource={Binding} x:Name=listCast/> </controls:PanoramaItem> <!--Panorama item four--> <controls:PanoramaItem Header=poster> <Image x:Name=imgPoster/> </controls:PanoramaItem> </controls:Panorama> </Grid>
Next, we should override the OnNavigatedTo method to set the data context for the bindings, but the method looks identical with the one shown for the pivot page so I wont list it again. Changes to the main page are minimal and very similar with what we did for the pivot page.
IMDb movie = new IMDb(response); PhoneApplicationService.Current.State[movie] = movie; if (rbtnPivot.IsChecked.HasValue && rbtnPivot.IsChecked.Value) { this.NavigationService.Navigate(new Uri(/MoviePivotPage.xaml, UriKind.Relative)); } else if (rbtnPanorama.IsChecked.HasValue && rbtnPanorama.IsChecked.Value) { this.NavigationService.Navigate(new Uri(/MoviePanoramaPage.xaml, UriKind.Relative)); }
58
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
If you compare this image strip with the one for the pivot page you can immediately see some differences: the size of the title is much bigger for panorama, which leaves less space for the panorama items content vertically. On the other hand, the horizontal size is also less with the panorama, because of the aesthetic nature of panorama which creates the impression of a single, continuous canvas, with left part of the next item also visible on the screen. When you run the application and sweep the screen you can notice another difference in the transition between two items of the pivot and panorama: pivot items slide swiftly into the view, while panorama items transit smoothly through the screen, creating the impression of the continuous canvas. Panorama defines a single event, SelectionChanged. The loading and unloading events dont make sense for panorama, because this control is basically a big single canvas, everything being loaded at the same time.
Summary
Pivot and Panorama are two WP7 specific controls with many similarities, yet some important aesthetic differences, such as the transition between the items, or the size and span of the title. You can easily switch between the two; basically all you have to do is replacing Pivot with Panorama and PivotItem with PanoramaItem. Though they are primarily design to be used in the portrait layout, they also work with the panorama layout. You should read the UI Design and Interactions Guide for Windows Phone 7 to learn more about when you should use the two and what rules you should follow.
59
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Chapter 7
identifier you provide. MarketplaceHubTask: launches the Windows Phone Marketplace client application. MarketplaceReviewTask: launches the Windows Phone Marketplace client application which then displays the review page for your application. MarketplaceSearchTask: launches the Windows Phone Marketplace client application which then shows the search results based on search terms you provide. MediaPlayerLauncher: launches the Media Player application and plays the media file you specify. PhoneCallTask: launches the Phone application and displays the specified phone number and display name. SearchTask: launches the Search application and performs search query you provide. SmsComposerTask: launches the Messaging application which displays a new SMS message. WebBrowserTask: launches the Web browser and displays the URL you provide.
Launchers
Launchers are APIs that allow applications to do common tasks such as making a phone call, sending an SMS or browsing the web. When a launcher is called, the application is tombstoned. After the launcher terminates, the application is activated again. Launchers do not return any data to the calling application. The following launchers are available in the Microsoft. Phone.Tasks namespace from the Microsoft.Phone assembly: EmailComposerTask: launches the Email application and displays a new email message MarketplaceDetailTask: launches the Windows Phone Marketplace client application which then shows the details page for a product specified by the unique
60
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
If you run the application youll notice the phone call is not made until the user presses the call button in the Phone application. When the phone call ends, the launcher terminates and the application is re-activated. The image strip below shows several screen shots of the application and the launcher.
61
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
The next image strip shows the application and the web browser after starting the launcher.
62
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Choosers
Choosers are APIs similar to launchers; however they return a value to the calling application. They are enabling common tasks such as taking a photo or selecting a phone number from the contacts list. The following choosers are available: CameraCaptureTask: launches the Camera application. EmailAddressChooserTask: launches the Contacts application and allows the user to select a contact. PhoneNumberChooserTask: launches the Contacts application and allows the user to select a contact. PhotoChooserTask: launches the Photo Picker application. SaveEmailAddressTask: saves the provided email address to the Contacts list. SavePhotoNumberTask: saves the provided phone number to the Contacts list. All these chooser classes are derived from the ChooserBase class. This is a generic class with the type argument representing the type of the event handler arguments for its single event called Completed. This event occurs when the chooser task is completed. You should handle this event to get the result from the chooser.
public event EventHandler<TTaskEventArgs> Completed;
Note: the SavePhotoNumberTask chooser does not return any data, but you can still handle the Completed event to check whether the task was successfully completed. The next demo application shows how to use the camera to take pictures and then display them in your application in a list. If youre using the emulator you can still take pictures, because the emulator simulates this action. It has a small application with a black rectangle moving across a white background. When you hit the button to capture the picture it saves the current image, and if you accept it, it returns the picture to your application. The XAML code below shows the content panel with the list, whose items are composed of an image and a text block, and the application bar with a single button that starts the chooser.
<!--ContentPanel - place additional content here--> <Grid x:Name=ContentPanel Grid.Row=1 Margin=12,0,12,0> <ListBox x:Name=listPictures> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation=Horizontal> <Image Width=64 Margin=5,5,5,5 Source={Binding Picture} /> <TextBlock Text={Binding Caption} Style={StaticResource PhoneTextTitle2Style} /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate>
63
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
</ListBox> </Grid>
<!--Sample code showing usage of ApplicationBar--> <phone:PhoneApplicationPage.ApplicationBar> <shell:ApplicationBar IsVisible=True IsMenuEnabled=True> <shell:ApplicationBarIconButton IconUri=/Images/appbar.feature.camera.rest.png Text=take picture x:Name=btnCamera Click=btnCamera_Click/> </shell:ApplicationBar> </phone:PhoneApplicationPage.ApplicationBar>
The view model used for the list items looks like this:
public class ListboxItemViewModel : INotifyPropertyChanged { private string _Caption; public string Caption { get { return _Caption; } set { if (value != _Caption) { _Caption = value; NotifyPropertyChanged(Caption); } } } private BitmapImage _Picture; public BitmapImage Picture { get { return _Picture; } set
64
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
{ if (value != _Picture) { _Picture = value; NotifyPropertyChanged(Picture); } } } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(String propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (null != handler) { handler(this, new PropertyChangedEventArgs(propertyName)); } } }
What we have to do now is creating an instance of CameraCaptureTask and in the constructor add a handler for the Completed event. When the user presses the take picture app bar button, we start the chooser by calling Show. In the handler for the Completed event, we check whether the task completed successfully, and if so we retrieve the bitmap image from the result stream and add a new item to the list.
public partial class MainPage : PhoneApplicationPage { CameraCaptureTask m_cameratask = new CameraCaptureTask(); int m_counter; public MainPage() { InitializeComponent(); m_cameratask.Completed += new EventHandler<PhotoResult>(cameratask_Completed); } void cameratask_Completed(object sender, PhotoResult e) { if (e.TaskResult == TaskResult.OK) { BitmapImage bmp = new BitmapImage(); bmp.SetSource(e.ChosenPhoto);
65
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
listPictures.Items.Add(new ListboxItemViewModel() { Picture = bmp, Caption = String.Format(image{0:D3}, ++m_counter) }); } } private void btnCamera_Click(object sender, EventArgs e) { m_cameratask.Show(); } }
Remember the application is tombstoned when a launcher or chooser starts and re-activated when it completes. The following handlers are called (in this order) when you press the take picture button, take a picture and then return to the application (supposing you overrode OnNavigatedFrom and OnNavigatedTo for the main page): OnNavigatedFrom Application_Deactivated Application_Activated cameratask_Completed OnNavigatedTo The image strip below shows the application initially, then the Camera application that allows you to take a picture (unfortunately the black rectangle on the white background image is not visible in these shots) and then the application again after taking several pictures.
66
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Summary
Launchers and choosers are Windows Phone APIs that enable applications to perform common tasks such as making phone calls, sending SMS, talking pictures or opening a web page in the browser. Choosers only differ from launcher in the way they complete, because they return some data to the calling application. When a launcher or chooser is called, the application is tombstoned, and then re-activated again when launcher/chooser completes. In this chapter weve seen how to use PhoneCallTask to make phone calls, and WebBrowserTask to open a URL in a browser. We also looked at the CameraCaptureTask to access the camera and take pictures and saw how to handle the Completed event to retrieve the data returned by the chooser.
67
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Chapter 8
Touch
indows Phone application can support different input methods: touch, on-screen keyboard, hardware keyboard, sensors, microphone and phone hardware buttons. This chapter will focus on touch. Users can manipulate the applications with single or multi-touch gestures. Single gestures (operations performed with a single hand) are tap, double tap, pan, flick and touch and hold. Multi-touch gestures are pinch and stretch. WP7 supports multi touch gestures with at least four fingers. Touch gesture are exposed through events to developers. There are two programming interfaces available for multi-touch: low-level and high-level. In addition, the Silverlight for Windows Phone Toolkit, a Microsoft project available on codeplex.com, offers even a higher-level support for multi-touch. If you run with the emulator, the mouse activity is converted to touch. However, you will be able to test only the single-touch gestures. For implementing support for multi-touch gesture you should use a real phone. In this chapter you will learn: How to use the low-level touch interface How to use the high-level touch interface How to use the higher-level touch interface from the Silverlight for Windows Phone Toolkit
and fires the FrameReported event. You can handle this event to get all touch events for your application. The TouchFrameEventArgs has the following members: Timestamp, a property representing an integer timestamp value of the event. GetPrimaryTouchPoint(), returns the primary touch point for the reported frame GetTouchPoints(), returns all the touch points in the reported frame SuspendMousePromotionUntilTouchUp(), disables automatic mouse-event promotion for the primary touch point until all the touch points report as TouchAction.Up. Methods GetPrimaryTouchPoint and GetTouchPoints return touch points either relative to particular element (passed as argument) or to the upper-left corner of the screen (when null is passed as argument). However, they dont limit the touch events for a particular element. You always get touch events for the entire application. The only thing you can do is calculating the Position property (see below) relatively to an UI element.
Low-Level Touch
The low-level interface is represented basically by a single event, called FrameReported in the static class Touch. The class is an application-level service that processes multi-touch input from the operating system
68
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
What we have to do is: Install a handler for the Touch.FrameReported event (in the constructor) Start a timer that increases the size of the rectangle, until a maximum point when it is reset In the handler get the primary touch point and if the DirectlyOver property indicates the rectangle start or stop the timer that inflates the rectangle. The implementation is shown below.
public partial class MainPage : PhoneApplicationPage { DispatcherTimer m_timer; const int OriginalSize = 100; public MainPage() {
69
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
InitializeComponent(); ResetSize(); m_timer = new DispatcherTimer(); m_timer.Interval = TimeSpan.FromMilliseconds(50); m_timer.Tick += (s, e) => { rectangle.Width += 5; rectangle.Height += 5; if (rectangle.Width >= 4 * OriginalSize || rectangle.Height >= 4 * OriginalSize) ResetSize(); }; Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported); } void ResetSize() { rectangle.Width = OriginalSize; rectangle.Height = OriginalSize; } void Touch_FrameReported(object sender, TouchFrameEventArgs e) { TouchPoint ppoint = e.GetPrimaryTouchPoint(null); if (ppoint != null && ppoint.TouchDevice.DirectlyOver == rectangle) { switch (ppoint.Action) { case TouchAction.Down: m_timer.Start(); break; case TouchAction.Up: m_timer.Stop(); break; } } } }
70
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
To complicate things a little bit well add support for double tap: if you tap twice on the rectangle in less than a given interval (lets say 250 milliseconds) well consider this a double tap, and in this case reset the size of the rectangle to its initial value. The changes in code are minimal: just add a DateTime member to the class (m_lastclick) and then if the Action is TouchAction.Down check the time elapsed since the last click; if the interval is less than 250 milliseconds reset the size, otherwise just start the timer.
71
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
case TouchAction.Down: { var now = DateTime.Now; var diff = now - m_lastclick; m_lastclick = now; if (diff.TotalMilliseconds < 250) { if (m_timer.IsEnabled) m_timer.Stop(); ResetSize(); } else m_timer.Start(); } break;
High-Level Touch
The high-level interface is represented by three events specific to an UI element. These events are: ManipulationStarted: occurs when an input device starts the manipulation of an element. ManipulationDelta: occurs when the input device changes position during manipulation. ManipulationCompleted: occurs when the manipulation of the UI element is complete. You can install handlers for these events for any UI element, but you can also handle them at page level. The Control class (which is the base class for UI elements that use a ControlTemplate to define their appearance) from which PhoneApplicationPage is derived has protected virtual methods called when these events occur.
protected virtual void OnManipulationCompleted(ManipulationCompletedEventArgs e); protected virtual void OnManipulationDelta(ManipulationDeltaEventArgs e); protected virtual void OnManipulationStarted(ManipulationStartedEventArgs e);
In this later case, you have to check the original source of the event to distinguish between the controls that raised the events. It is also possible to use both handlers at the control level and page level. That means you can actually handle the same event twice, and even do different things. This is possible because the events are routed from the topmost element for which the event was fired, up the visual tree until the frame element, so anyone interested can handle the event. All the manipulation events derive from RoutedEventArgs type which contains a property called OriginalSource that indicates the element where the event began. However, you can prevent the event to travel up the visual tree by setting the Handled property that all the manipulation events have, to true. That indicates that the event has been handled and should not be routed up the tree. To demonstrate the handling of manipulation events well create a simple implementation of the famous Pong game. There is a board with two paddles on the left and right sides which you can move up and down. A ball bounces from 72
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
73
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
74
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
75
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Higher-Level Touch
A higher-level support for multi-touch gestures is provided with the Silverlight for Windows Phone Toolkit available for download on codeplex at http://silverlight.codeplex.com. This toolkit contains controls you can use in your WP7 Silverlight applications such as WrapPanel, DatePicker and TimePicker, AutoCompleteBox and others. In addition it contains a GestureListener that provides support to detect gestures in your applications. The following gestures are supported: Tap Double-tap Hold Flick Drag; three events can be used to implement dragging: DragStarted, DragDelta and DragCompleted Pinch; three events are available to implement pinching (for instance zooming in or out): PinchStarted, PinchDelta, PinchCompleted To use the toolkit you first have to download and install it and then add a reference to the Microsoft.Phone.Controls. Toolkit assembly to your project. The following demo shows how to handle some of the events for these gestures. The content of the main page is represented by a stack panel with a border that encapsulates a text block and a list. Each time a gesture event happens on the border element, a text identifying the gesture is added to the list. The gesture handlers will be installed for the border (used only to act as a background to the TextBlock and highlight the area where you can exercise the gestures). First, we must add the following namespace to the PhoneApplicationPage definition.
xmlns:toolkit=clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit
76
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
<TextBlock x:Name=txtTouch Text=Touch here Foreground=Black TextAlignment=Center VerticalAlignment=Center Style={StaticResource PhoneTextTitle2Style}/> </Border> <ListBox x:Name=listEvents /> </StackPanel> </Grid>
77
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Summary
Touch is an important part of the WP7 applications. Users interact with the device with the finger and the system supports multi-touch events with at least four fingers. There are different levels of support for the touch events. In this chapter we looked at the low level interface and handled the Touch.FrameReported event to get touch information for the entire application. Then we looked at the high-level support and learnt how we can handle the three touch event specific to an UI element, called ManipulationStarted, ManipulationDelta and ManipulationCompleted. Last, we had a quick look at the Silverlight for Windows Phone Toolkit support for touch. You can use the one that you find most appropriate for your needs.
78
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Chapter 9
Create an account on the Bing Maps Portal and obtain a new authentication key Add a Map control to your application and use the key from the maps portal Change the map mode from Aerial to Road Add a push pin to the map
Getting Started
To get started with using the Bing Maps control in your Bing Maps application, you will need to get a Bing Maps key which is available by registering at https://www. bingmapsportal.com/. If you do not have a Windows Live profile, you will be prompted to create one. If you have one, you can just sign in.
79
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Once you have your account created, you will see the Create or view Keys link on the left side of the page. Click that to create or retrieve your key. You will be asked to fill in the description of your application. You should get a key because they are the recommended authentication method for the Bing Maps AJAX Control, the Bing Maps Silverlight Control, the Bing Maps SOAP Services, the Bing Maps REST Services, and the Bing Spatial Data Services. You can create up to five Bing Maps keys.
80
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
We will use this key in our Bing maps application. Complete details of getting a Bing Maps key for use in your application are available here: http://go.microsoft.com/fwlink/?LinkID=198152.
81
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
To fix that issue, let us use the Bing Maps key we just obtained above in our application. Here is the change we make to add the key. Note that adding the Bing Maps key directly in the XAML file is not recommended. Use a resource to assign the value.
<my:Map Name=map1 Height=375 Width=456 HorizontalAlignment=Left VerticalAlignment=Top CredentialsProvider=AtZjYxf45FIyRhN9hhrWbSCYzT8AjyoEbHQq8PNVr9iiO6dgZXJEw/>
If you want to change the default view rendered, you can set the mode to Aerial instead of the default Road. For our application we will have a default of Aerial mode, so that we can see how the switch to road mode works. Change your XAML file to add the Mode property to the Map control.
<my:Map Name=map1 Height=375 Width=456 HorizontalAlignment=Left VerticalAlignment=Top CredentialsProvider=AtZjYxf45FIyRhN9hhrWbSCYzT8AjyoEbHQq8PNVr9iiO6dgZXJEw Mode=Aerial/>
82
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Let us add the functionality to switch between Aerial and Road mode on the maps. Go ahead and add two buttons on the main page. Rename the content of the buttons to Aerial and Road. The XAML code for the content panel could look like this:
<!--ContentPanel - place additional content here--> <Grid x:Name=ContentPanel Grid.Row=1 Margin=12,0,12,0> <StackPanel Grid.Row=0> <my:Map Name=map1 Height=375 Width=456 HorizontalAlignment=Left VerticalAlignment=Top CredentialsProvider=AtZjYxf45FIyRhN9hhrWbSCYzT8AjyoEbHQq8PNVr9iiO6dgZXJEw Mode=Aerial/>
83
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
<StackPanel Orientation=Horizontal> <Button Name=buttonRoad Content=Road Click=buttonRoad_Click/> <Button Name=buttonAerial Content=Aerial Click=buttonAerial_Click/> </StackPanel> </StackPanel> </Grid>
Now on the Road button, double click the button so that the event handler for Click is created. Repeat the same operation for the Aerial button. In the event handlers, add the following code: private void buttonRoad_Click(object sender, RoutedEventArgs e) { Microsoft.Phone.Controls.Maps.Core.MapMode m = new Microsoft.Phone.Controls.Maps.RoadMode(); map1.SetMode(m, true); } private void buttonAerial_Click(object sender, RoutedEventArgs e) { Microsoft.Phone.Controls.Maps.Core.MapMode m = new Microsoft.Phone.Controls.Maps.AerialMode(); map1.SetMode(m, true); } Note that the only difference in the above code snippets is the MapMode; in one, it is RoadMode and in the other it is AerialMode. Now, to fancy our application, let us add a PushPin. For that, we need to create an instance of the Pushpin class. Let us start by adding a button with content Add Push Pin which will create a pushpin on the center of the currently visible map area. Double click the button to wire up the Click event handler and add the following code in the handler.
private void buttonPushPin_Click(object sender, RoutedEventArgs e) { Microsoft.Phone.Controls.Maps.MapLayer pushPinLayer = new Microsoft.Phone.Controls.Maps.MapLayer(); map1.Children.Add(pushPinLayer); TextBlock textBlock = new TextBlock(); textBlock.Text = DemoPushpin; Grid grid = new Grid(); grid.Children.Add(textBlock);
84
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Microsoft.Phone.Controls.Maps.Pushpin p = new Microsoft.Phone.Controls.Maps.Pushpin(); p.Location = map1.Center; pushPinLayer.AddChild( p, map1.Center, Microsoft.Phone.Controls.Maps.PositionOrigin.Center); pushPinLayer.AddChild( grid, map1.Center, Microsoft.Phone.Controls.Maps.PositionOrigin.Center); }
If you run this application, you can see that by default the world map is visible in the Aerial mode. Now you can zoom to a place of your choice and click on the Aerial and Road buttons to switch the view between Aerial view and Road view. To add a push pin, click the Add Push Pin button which will add a push pin in the center of the currently visible area. To ensure that the push pin has some context, we added a label with the pin called DemoPushpin (see the code above). The following image shows the application with the map zoomed over Europe and a push pin added to the center of the map.
Summary
In this chapter we looked at the process of creating applications using Bing Map control. We first looked at how you can create an account on Bing Maps Portal and obtain a new key to use with the map in your application for authentication purposes. We then created a simple application and added a Map control to the content panel. We changed the view mode between Aerial and Road and saw how to add a push pin to the map. Hopefully you would have found the information useful and will be able to create some great mapping applications.
85
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Chapter 10
XAP file of the application being submitted The price you want to charge for your application At the time of writing this eBook, the marketplace was opened for developers from 17 countries and regions. If you are not from one of these countries and want to submit to the marketplace you must find a workaround like teaming with someone from an eligible country. To begin the application submission process, you need to navigate to this link https://windowsphone.create.msdn. com/AppSubmission and log in using your Windows Live Account (if you have not done so already).
Enter the name of the application, the platform it will run on, the default language of its application and the version. To upload your XAP file, click the + sign and select your file.
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
The application title is how your application will show up in the Windows Phone Marketplace. Make sure to select a name which is intuitive enough for the user community to remember. If your application is a game and you have a certification for it, you can specify the ESRP rating it has received. Since only five keywords are allowed, be smart about your keyword choices.
87
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
You can choose to have your application automatically published to the Marketplace if it passes certification. Click Submit for certification and you are done.
88
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Summary
All Windows Phone applications are made available through the Windows Phone Marketplace. You must have a developer account at App Hub (for a yearly fee) in order to be able to submit applications. A submitted application goes through a review process and if it meets the certification requirements it is published. This chapter described the submission process step by step.
89
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
References
Windows Phone Development 7000 apps and counting on WP7 Marketplace
http://msdn.microsoft.com/en-us/library/ ff402535%28VS.92%29.aspx
Silverlight for Windows Phone (MSDN)
http://www.1800pocketpc.com/2011/01/28/7000-appsand-counting-on-wp7-marketplace.html
Abhinay Rathore , ASP.net/C# IMDb Scraping API
http://msdn.microsoft.com/en-us/library/ ff426934%28v=VS.95%29.aspx
UI Design and Interaction Guide for Windows Phone 7 v2.0
http://web3o.blogspot.com/2010/11/aspnetc-imdbscraping-api.html
Vincent Leung, Windows Phone 7 Cheat Sheet
http://go.microsoft.com/fwlink/?LinkID=183218
Charles Petzold, Programming Windows Phone 7
http://vincenthomedev.wordpress.com/2010/10/30/ windows-phone-7-cheat-sheet/
Cheryl Simmons, Windows Phone 7 Design Guidelines Cheat Sheet
http://www.charlespetzold.com/phone/index.html
Scott Guthrie, Windows Phone 7 Developer Tools Released
http://weblogs.asp.net/scottgu/archive/2010/09/16/ windows-phone-7-developer-tools-released.aspx
Windows Phone 7 Application Certification Requirements
http://blogs.msdn.com/b/silverlight_sdk/ archive/2011/01/07/windows-phone-7-design-guidelinescheat-sheet.aspx?wa=wsignin1.0
Adam Kinney, Windows Phone 7 Gestures Cheat Sheet
http://go.microsoft.com/fwlink/?LinkID=183220
James Ashley, WP7 Tombstoning Pattern Tip
http://adamkinney.com/blog/2010/09/23/windowsphone-7-gestures-cheat-sheet/
Windows 7 eBook Code Samples
http://www.imaginativeuniversal.com/blog/ post/2010/08/22/WP7-Tombstoning-Pattern-Tip.aspx
James Ashley, WP7 Tip: tombstoning simplified
http://www.codeguru.com/img/2010/12/WP7book_ sourcecode.zip
http://www.imaginativeuniversal.com/blog/ post/2010/08/26/WP7-Tip-tombstoning-simplified.aspx
90
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.
Vipul Patel is a Software Engineer currently working at Microsoft Corporation, working in the Office Communications
Group and has worked in the .NET team earlier in the Base Class libraries and the Debugging and Profiling team. He can be reached at vipul_d_patel@hotmail.com.
91
Back to Contents
Windows Phone 7 Quick Start Developer Guide an Internet.com Developer eBook. 2011, Internet.com, a division of QuinStreet, Inc.