This chapter is taken from book "Programming Windows Phone 7" by Charles Petzold published by Microsoft press. http://www.charlespetzold.com/phone/index.html
We want our phones to be much like our other computers. We want to have a lot of applications available. We want to start up a particular application as soon as we conceive a need for it. While that application is running, we want it to be as fast as possible and have access to unlimited resources. But we want this application to coexist with other running applications because we want to be able to jump among multiple applications running on the machine.
Windows Phone 7 manages multiple active applications by implementing a stack. In a sense, this application stack extends the page stack within a single Silverlight program. You can think of the phone as an old-fashioned web browser with no tab feature and no Forward button. But it does have a Back button and it also has a Start button, which brings you to the Start screen and allows you to launch a new program.
Page State
The SilverlightFlawedTombstoning project is a simple Silverlight program with
just one page. The program responds to taps on the screen by changing the
background of ContentGrid to a random color, and displaying the total number of
taps in its page title. Everything of interest happens in the code-behind file:
namespace
SilverlightFlawedTombstoning
{
public partial
class MainPage
: PhoneApplicationPage
{
Random rand =
new Random();
int numTaps = 0;
public MainPage()
{
InitializeComponent();
UpdatePageTitle(numTaps);
}
protected
override void OnManipulationStarted(ManipulationStartedEventArgs
args)
{
ContentPanel.Background = new
SolidColorBrush(Color.FromArgb(255,
(byte)rand.Next(256),
(byte)rand.Next(256),
(byte)rand.Next(256)));
UpdatePageTitle(++numTaps);
args.Complete();
base.OnManipulationStarted(args);
}
void UpdatePageTitle(int
numTaps)
{
PageTitle.Text = String.Format("{0}
taps total", numTaps);
}
}
}
The little UpdatePageTitle method is called from both the program's constructor (where it always results in displaying a value of 0) and from the OnManipulationStarted override.
Build and deploy the program to the phone or phone emulator by pressing F5 (or selecting Start Debugging from the Debug menu). Arrange Visual Studio so you can see the Output window. When the program starts up, tap the screen several times to change the color and bump up the tap count. Now press the phone's Start button. You can see from Visual Studio that two threads in the program end and the program has terminated, but to the phone the program has actually been deactivated and tombstoned.
Now press the Back button to return to the program. You'll see a blank screen with the word "Resuming…" and the Output window in Visual Studio shows libraries being loaded. That's the program coming back to life.
Although Windows Phone 7 leaves much of the responsibility for restoring a tombstoned application to the program itself, it will cause the correct page to be loaded on activation, so it's possible that a page-oriented Silverlight program that saves and restores page state data using the State property of PhoneApplicationSerivce class during OnNavigatedTo and OnNavigatedFrom will need no special processing for tombstoning. The phone operating system preserves this State property during the time a program is deactivated and tombstoned, but gets rid of it when the program closes and is terminated for real.
The code-behind file for SilverlightBetterTombstoning
includes a using
directive for
Microsoft.Phone.Shell and uses this
State dictionary.
Here's the complete class:
namespace SilverlightBetterTombstoning
{
public partial
class MainPage
: PhoneApplicationPage
{
Random rand =
new Random();
int numTaps = 0;
PhoneApplicationService appService =
PhoneApplicationService.Current;
public MainPage()
{
InitializeComponent();
UpdatePageTitle(numTaps);
}
protected
override void OnManipulationStarted(ManipulationStartedEventArgs
args)
{
ContentPanel.Background = new
SolidColorBrush(Color.FromArgb(255,
(byte)rand.Next(256),
(byte)rand.Next(256),
(byte)rand.Next(256)));
UpdatePageTitle(++numTaps);
args.Complete();
base.OnManipulationStarted(args);
}
void UpdatePageTitle(int
numTaps)
{
PageTitle.Text = String.Format("{0}
taps total", numTaps);
}
protected
override void OnNavigatedFrom(NavigationEventArgs
args)
{
appService.State["numTaps"] =
numTaps;
if (ContentPanel.Background
is SolidColorBrush)
{
appService.State["backgroundColor"]
= (ContentPanel.Background as
SolidColorBrush).Color; }
base.OnNavigatedFrom(args);
}
protected
override void OnNavigatedTo(NavigationEventArgs
args)
{
// Load numTaps
if (appService.State.ContainsKey("numTaps"))
{
numTaps = (int)appService.State["numTaps"];
UpdatePageTitle(numTaps);
}
// Load background color
object obj;
if (appService.State.TryGetValue("backgroundColor",
out obj))
ContentPanel.Background = new
SolidColorBrush((Color)obj);
base.OnNavigatedTo(args);
}
}
}
Notice the appService field set to PhoneApplicationService.Current. That's just for convenience for accessing the State property. You can use the long PhoneApplicationService.Current.State instead if you prefer.
Isolated Storage
Every program installed on Windows Phone 7 has access to its own area of permanent disk storage referred to as isolated storage, which the program can access using classes in the System.IO.IsolatedStorage namespace. Whole files can be read and written to in isolated storage, and I'll show you how to do that in the program that concludes this chapter. For the program that following I'm going to focus instead on a special use of isolated storage for storing application settings. The IsolatedStorageSettings class exists specifically for this purpose.
For the SilverlightIsolatedStorage program, I decided that the number of taps should continue to be treated as transient data-part of the state of the page. But the background color should be an application setting and shared among all instances.
App.xaml.cs has empty event handlers for all the
PhoneApplicationService
events. I gave each handler a body consisting of a single
method call and the LoadSettings
and SaveSettings
methods. Both methods obtain an
IsolatedStorageSettings
object. Like the State
property of
PhoneApplicationService, the
IsolatedStorageSettings
object is a dictionary. One method in the program loads
(and the other saves) the Color
property of the
BackgroundBrush property:
public
partial
class
App
: Application
{
//
Application settings
public
Brush
BackgroundBrush { set;
get;
}
// Easy
access to the root frame
public
PhoneApplicationFrame
RootFrame { get;
private
set;
}
//
Constructor
public
App()
{
// Global handler for uncaught exceptions.
// Note that exceptions thrown by
ApplicationBarItem.Click will not get caught here.
UnhandledException += Application_UnhandledException;
// Standard Silverlight initialization
InitializeComponent();
// Phone-specific initialization
InitializePhoneApplication();
}
// 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)
{
LoadSettings();
}
// 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)
{
LoadSettings();
}
// 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)
{
SaveSettings();
}
// 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)
{
SaveSettings();
}
void
LoadSettings()
{
IsolatedStorageSettings settings =
IsolatedStorageSettings.ApplicationSettings;
Color clr;
if (settings.TryGetValue<Color>("backgroundColor",
out
clr))
BackgroundBrush = new
SolidColorBrush(clr);
}
void
SaveSettings()
{
IsolatedStorageSettings settings =
IsolatedStorageSettings.ApplicationSettings;
if (BackgroundBrush
is
SolidColorBrush)
{
settings["backgroundColor"]
= (BackgroundBrush as
SolidColorBrush).Color;
settings.Save();
}
}
}

Join the conversation! Your thoughts help the community grow.