This site uses cookies for analytics, personalized content and ads. By continuing to browse this site, you agree to this use. Learn more
Microsoft Logo
Gray Pipe
  • Developer Network
    • Downloads
      • Visual Studio
      • SDKs
      • Trial software
    • Programs
      • Subscriptions
      • Students
      • ISV
      • Startups
      • Events
    • Community
      • Magazine
      • Forums
      • Blogs
      • Channel 9
    • Documentation
      • APIs and reference
      • Dev centers
      • Samples
      • Retired content
Developer Network Developer

Subscriber portal

Get tools
magazine
  • Issues and downloads
    • All issues
    • 2019
      • March 2019
      • February 2019
      • January 2019
    • 2018
      • Connect(); 2018
      • December 2018
      • November 2018
      • October 2018
      • September 2018
      • August 2018
      • July 2018
      • June 2018
      • May 2018
      • April 2018
      • March 2018
      • February 2018
      • January 2018
    • 2017
      • Connect(); 2017
      • December 2017
      • November 2017
      • October 2017
      • September 2017
      • August 2017
      • July 2017
      • June 2017
      • May 2017
      • April 2017
      • March 2017
      • February 2017
      • January 2017
    • 2016
      • December 2016
      • Connect(); 2016
      • November 2016
      • October 2016
      • September 2016
      • August 2016
      • July 2016
      • June 2016
      • May 2016
      • April 2016
      • March 2016
      • February 2016
      • January 2016
    • 2015
      • December 2015
      • November 2015
      • Windows 10 issue
      • October 2015
      • September 2015
      • August 2015
      • July 2015
      • June 2015
      • May 2015
      • April 2015
      • March 2015
      • February 2015
      • January 2015
    • 2014
      • Special 2014
      • December 2014
      • November 2014
      • October 2014
      • September 2014
      • August 2014
      • July 2014
      • June 2014
      • May 2014
      • April 2014
      • March 2014
      • February 2014
      • January 2014
    • 2013
      • Government 2013
      • December 2013
      • November 2013
      • October 2013
      • September 2013
      • August 2013
      • July 2013
      • June 2013
      • May 2013
      • April 2013
      • March 2013
      • February 2013
      • January 2013
    • 2012
      • December 2012
      • November 2012
      • Windows 8
      • October 2012
      • September 2012
      • August 2012
      • July 2012
      • June 2012
      • May 2012
      • April 2012
      • March 2012
      • February 2012
      • January 2012
    • 2011
      • December 2011
      • November 2011
      • October 2011
      • September 2011
      • August 2011
      • July 2011
      • June 2011
      • May 2011
      • April 2011
      • March 2011
      • February 2011
      • January 2011
    • 2010
      • December 2010
      • November 2010
      • October 2010
      • September 2010
      • August 2010
      • July 2010
      • June 2010
      • May 2010
      • April 2010
      • March 2010
      • February 2010
      • January 2010
    • 2009
      • December 2009
      • November 2009
      • October 2009
      • September 2009
      • August 2009
      • July 2009
      • June 2009
      • May 2009
      • April 2009
      • March 2009
      • February 2009
      • January 2009
  • Subscribe
  • Submit article
search clear
We’re sorry. The content you requested has been removed. You’ll be auto redirected in 1 second.
Issues and downloads 2012 January 2012 Windows Phone 7 - Your First Windows Phone Application

January 2012
Volume 27 Number 01

Windows Phone - Your First Windows Phone Application

By Jesse Liberty | January 2012

The trick in writing a first Windows Phone application is to build something interesting enough to be meaningful, yet simple enough to actually get underway. Toward that end, I’ll walk you through creating a simple utility that I use every day: NoteToMe. The idea is that you can enter a message and send it to yourself by pressing one button, as shown in Figure 1.

The NoteToMe Interface
Figure 1 The NoteToMe Interface

Note that this article will touch on a number of topics, each of which will be expanded upon at some length in subsequent articles. These topics include:

  • Creating the layout of the application
  • Storing and retrieving data from Isolated Storage
  • Events and event handling
  • Creating and running tasks (launchers and choosers)

Before you can begin, you’ll need to download the tools from create.msdn.com. If you’ve already unlocked your phone but not yet upgraded to Windows Phone 7.5 (“Mango”), now is the time to do so; Mango brings hundreds of new features to the Windows Phone OS.

Getting Started

Like many Windows Phone developers, I’ve come to believe that the best tool for creating Windows Phone applications is a combination of Visual Studio (for code) and Expression Blend (for everything else). Thus, we’ll begin by opening Expression Blend and creating a new application named NoteToMe, based on the Windows Phone SDK 7.1.

Let’s start by changing the application title. Click on the title, and in the Properties window find the Text property for that control. The Metro design guidelines (the design guidelines for Windows Phone) call for the title to be in all caps, so change the title to NOTE TO ME.

Click on the page title and hit Delete to remove it.

To create the layout, you’ll need a small row near the top of the page. Click in the margin to bring up a guideline that helps you visually select where to place the row, as shown in Figure 2.

Placing the Top Row of the Layout
Figure 2 Placing the Top Row of the Layout

Of course, you can set the row size by hand directly in the XAML:

XML
Copy
<Grid.RowDefinitions>
  <RowDefinition Height="1*"/>
  <RowDefinition Height="9*"/>
</Grid.RowDefinitions>

The asterisk after the value indicates relative sizing—in this case 1:9. That is, the first row will be one-ninth of the size of the second row. 

Adding Three Controls to the StackPanel

The top row will have three controls in it, side by side:

  • A TextBlock acting as a label
  • A TextBlock to hold the e-mail address
  • A Button to send the message

This design is shown in Figure 3.

Three Controls in the Top Row
Figure 3 Three Controls in the Top Row

You can’t put three controls into a single column of a row without putting them inside some sort of organizing container. I’ll use a StackPanel whose orientation has been set to horizontal—StackPanels stack on top of each other or next to each other.

To create a StackPanel, click on the tiny white arrow next to the Layout control on the toolbar as shown in Figure 4.

Adding a StackPanel
Figure 4 Adding a StackPanel

Click on the StackPanel to select the control. Now drag a StackPanel into the row and set its vertical and horizontal alignment to stretch and its margins to zero in the Layout window as shown in Figure 5.

Placing the StackPanel
Figure 5 Placing the StackPanel

Add the TextBlock, setting its font size to 32, and its text to To. Now drag a TextBox onto the StackPanel. (Note the important but subtle difference between a TextBlock, for displaying text, and a TextBox, for text input.) Name this TextBox Address. Finally, add a button to the StackPanel, name it Send and set its Content to Send.

The XAML this produces is shown in Figure 6.

Figure 6 Designing the StackPanel with XAML
XML
Copy
<StackPanel
  Margin="0"
  Orientation="Horizontal">
  <TextBlock
    Margin="0,8"
    TextWrapping="Wrap"
    Text="To"
    Width="42"
    HorizontalAlignment="Left"
    VerticalAlignment="Center"
    FontSize="32" />
  <TextBox
    x:Name="Address"
    Margin="0,0,0,-7"
    TextWrapping="Wrap"
    Text="foo@bar.com"
    Width="293" />
  <Button
    x:Name="Send"
    Content="Send"
    Margin="0,4,0,0"
    Width="124"
    Click="Send_Click" />
</StackPanel>

Notice the Send button has a Click=“Send_Click” property. You create this by clicking on the button, then in the Properties window, you click on the Events button, as shown in Figure 7.

The Events Button
Figure 7 The Events Button

This opens all the events for the button. Find the click event and double-click. The button is updated with the event, and you’re placed in the code editor (either in Blend or in Visual Studio, depending on how you have Blend set up) for that event handler. For now, you can leave this event handler as is:

XML
Copy
private void Send_Click( object sender, RoutedEventArgs e )
{
}

Adding the Message Control

Click on the TextBox control in the toolbar and then drag a TextBox out to fill half of the remaining page (we’re leaving the other half for the keyboard, which will appear when it’s time to enter something in the TextBox). Set the HorizontalAlignment to Stretch, the VerticalAlignment to Top, the margins to 0. Set the Width to Automatic and the height to 244. You can do all this by eye as you resize the TextBox, or you can draw the TextBox roughly in place and set the properties in the Properties window as shown in Figure 8.

Adding the TextBox
Figure 8 Adding the TextBox

Writing the Code

With the controls in place, you’re ready to work on the logic of the program. You should see a tab called Projects in the upper left corner. After saving all your changes, click the Projects tab, then right-click on MainPage.xaml.cs and select Edit In Visual Studio, as shown in Figure 9.

Getting Ready to Write the Code
Figure 9 Getting Ready to Write the Code

The Specification

My (self-imposed) specification says you shouldn’t have to fill in the To field each time you use the program; the To field should be prepopulated with whatever was in the To field the previous use.

Moreover, when you click Send, a new e-mail message should be prepared for your e-mail program, with all the fields prepopulated so that you can just press Send or, optionally, edit the message and then press Send.

Using Isolated Storage

To preserve the contents of the To field across usages of the application, you need to store the contents somewhere on the phone. This is what Isolated Storage is for: persisting data when the application is closed. As its name implies, Isolated Storage allows your application to store data isolated and protected from data stored by other applications. Using Isolated Storage is fairly straightforward.

First, add the using statement:

XML
Copy
using System.IO.IsolatedStorage;

Declare a member variable of type IsolatedStorageSettings and a constant string to act as a key into the Isolated Storage dictionary so you can store and retrieve the e-mail address:

XML
Copy
private IsolatedStorageSettings _isoSettings;
const string IsoKey = "EmailAddress";

Initialize the _isoSettings member in the constructor:

XML
Copy
_isoSettings = IsolatedStorageSettings.ApplicationSettings;

Storing and Retrieving the E-mail Address

The two tasks related to Isolated Storage are storing the string and retrieving it. Storing it is best done as you leave the page. When you leave any Windows Phone page, the method OnNavigatedFrom is called. You’re free to override it, and one good reason to do so is to store data in Isolated Storage, like this:

XML
Copy
protected override void OnNavigatedFrom( 
  System.Windows.Navigation.NavigationEventArgs e )
{
  _isoSettings[IsoKey] = Address.Text;
  base.OnNavigatedFrom( e );
}

Now you have the e-mail address stored in the _isoSettings dictionary under the IsoKey key. When you return to the page, you can restore this setting. I do this by calling the private helper method RestoreEmailAddress from the constructor:

XML
Copy
private void RestoreEmailAddress()
  {
    if (_isoSettings.Contains( IsoKey ))
      Address.Text = _isoSettings[IsoKey].ToString();
  }

Notice that I test for the existence of the key in Isolated Storage before trying to restore it—this averts a KeyNotFound exception the first time I run the program. Remember, the first time you run the program you haven’t yet stored anything in Isolated Storage.

When the program is first started, there’s nothing in the Address field. Once the user puts an e-mail address in the address field, that address is stored in Isolated Storage and restored the next time the program is run. If the user changes the address, that new address is the one restored.

Tasks

Windows Phone 7.5 supports a number of tasks for interacting with built-in phone applications (mail, contact list, the camera and so forth). There are two types of tasks: Launchers and Choosers. Choosers are used to select information and return it to your program (to obtain an e-mail address from the contact list, for example). Launchers are used to launch a program that doesn’t return data.

In this case, you have everything you need to send the message, so you can call the e-mail Launcher and supply the required fields. When you call Show on the e-mail Launcher, the e-mail application will be launched with your data, but you won’t get any data back (which is fine; you don’t need any).

After the e-mail is sent, you’re returned to the program in case you want to send another message.

All of the work of creating the Launcher is encapsulated within the click event handler for the Send button. Let’s begin by creating an instance of the EmailComposeTask (the Launcher). Fill in the fields and call Show. That’s all there is to it:

XML
Copy
private void Send_Click( object sender, RoutedEventArgs e )
{
  EmailComposeTask emailComposeTask = new EmailComposeTask();
  emailComposeTask.Subject = "Send To Me";
  emailComposeTask.To = Address.Text;
  emailComposeTask.Body = Message.Text;
  Message.Text = String.Empty;
  emailComposeTask.Show();
}

When you call Show, the subject, address and body of the message are passed to your e-mail application. If you have more than one e-mail application, you’re asked which one you’d like to use. A properly addressed and formatted e-mail message is created, ready for you to send.

The Application Lifecycle

If users could be relied on to never interrupt their use of your application until they sent the message, you’d be done. In reality, though, users will stop right in the middle of composing a message and launch a different application. When they return, they won't be happy if the work they did is gone.

To know how to protect against this, you need to understand a bit about the lifecycle of an application, and how you can preserve state while still supporting one of the most powerful features of Mango: Fast Application Switching.

When your application is launched (say from the Start menu), the Application Launching event is fired. Once the application is started, and every time the user navigates to your page, the OnNavigatedTo method is called, after which your page will be in the Running state. If the user starts a new application, your application receives the Application Deactivated event and is put in the dormant state. If the phone runs low on memory, your application may be tombstoned.

From either tombstoned or dormant, your application may be terminated or it may be restored. What we care about right now is what happens when your application is restored.

If your application is dormant, you not only don’t have to take any action when it’s restored, but you also don’t want to take any action; the state was preserved when the application was dormant, and it’s ready to go.

If your application was tombstoned, though, then you do want to restore your page state when the application returns so that it appears to the user that the application was running (or at least dormant) while it was switched away.

You therefore face two tasks:

  1. Save state when the page’s OnNavigatedFrom method is called.
  2. Potentially restore state when the page’s OnNavigatedTo method is called—restoring state if the app was tombstoned but not if it was dormant.

Saving State When the Page Is Going Away

Because you can’t know, when the page receives the OnNavigatedFrom, what state it will be in when it’s restored, you must store the state in case it will be needed. This is very easy to do: you use a State dictionary that’s very much like the Isolated Storage dictionary in its syntax, though you want to remember that the State dictionary is not written to permanent storage and is in fact destroyed when you exit the program or turn off the phone.

Let’s start by creating a constant string StateKey, which you’ll use as the offset into the State dictionary:

XML
Copy
const string StateKey = "MessageState";

In the OnNavigatedFrom method, you’ll store the state (in this case, the contents of the MessageBox) into the State dictionary:

XML
Copy
protected override void OnNavigatedFrom( 
  System.Windows.Navigation.NavigationEventArgs e )
{
  _isoSettings[IsoKey] = Address.Text;
  State[StateKey] = Message.Text;
  base.OnNavigatedFrom( e );
}

Restoring State When the Page Is Created

When the OnNavigatedTo method is called, you don’t want to take any action to restore State if the app was dormant, but you do want to take action if it was tombstoned.

You can distinguish between the dormant or tombstoned state by setting a flag to false, and then setting it to true in the constructor. If the app is dormant, the constructor will not be called; if it was tombstoned, the constructor will be called (because it will be the first time it’s constructed), like so:

XML
Copy
bool isNew = false;
  public MainPage()
  {
    InitializeComponent();
    isNew = true;

You can check that flag in OnNavigatedTo:

XML
Copy
protected override void OnNavigatedTo(
  System.Windows.Navigation.NavigationEventArgs e )
{
  if (isNew)
  {
    if (State.ContainsKey( StateKey ))
    {
      Message.Text = State[StateKey].ToString();
    }
  }
  isNew = false;
  base.OnNavigatedTo( e );
}

This test saves the time it would otherwise take to restore the value from the State dictionary. You can test this by first running your program normally (in which case when you switch to another application your program will go dormant) and then forcing the program to be tombstoned. You can force your program to be tombstoned by right-clicking on the project, choosing Properties, choosing the Debug tab and checking the checkbox Tombstone upon deactivation while debugging.

When you run with this checked, you’ll see a noticeable pause when returning to the page because the state must be restored.

Final Overview

In this brief article, I’ve shown you how to write your first non-trivial Windows Phone application. I began by creating the application in Expression Blend, where I created a row and used a StackPanel to lay out the controls.

I then switched to Visual Studio to write the logic for the button’s event handler, and used Isolated Storage to persist the e-mail address. I used State memory to ensure that the application would restart properly after being tombstoned.

As noted, there’s much more to say on each of these topics, and they’ll be covered in detail in future articles.


Jesse Liberty is a senior developer-community evangelist on the Windows Phone team. Liberty hosts the popular Yet Another Podcast (jesseliberty.com/podcast), and his blog (jesseliberty.com/) is required reading. He’s the author of numerous best-selling books, including “Programming Reactive Extensions and LINQ” (Apress, 2011) and “Migrating to Windows Phone,” (Apress, 2011). You can follow Liberty on Twitter at twitter.com/JesseLiberty.

Thanks to the following technical experts for reviewing this article: Drew Batchelor and Cheryl Simmons

MSDN Magazine Blog

 

More MSDN Magazine Blog entries >


Current Issue


March 2019

Browse All MSDN Magazines


Subscribe to MSDN Flash newsletter


Receive the MSDN Flash e-mail newsletter every other week, with news and information personalized to your interests and areas of focus.

Follow us
  • https://www.facebook.com/microsoftdeveloper
  • https://twitter.com/msdev
  • https://plus.google.com/111221966647232053570/
Sign up for the MSDN Newsletter
Is this page helpful?
Your feedback about this content is important.
Let us know what you think.
Additional feedback?
1500 characters remaining
Thank you!
We appreciate your feedback.

Dev centers

  • Windows
  • Office
  • Visual Studio
  • Microsoft Azure
  • More...

Learning resources

  • Microsoft Virtual Academy
  • Channel 9
  • MSDN Magazine

Community

  • Forums
  • Blogs
  • Codeplex

Support

  • Self support

Programs

  • BizSpark (for startups)
  • Microsoft Imagine (for students)
United States (English)
  • Newsletter
  • Privacy & cookies
  • Terms of use
  • Trademarks
logo © 2019 Microsoft