In the last article Part 8 - Windows Phone 7 sharing data among pages using OnNavigatedFrom everytime you navigate to SeconPage the second page starts out with same without retaining the color. The reason of this behaviour is due to different instance of SecondPage whenever you navigate to SecondPage. In this article we will discuss about retaining data across instances in Windows Phone 7.
To keep the color of the SecondPage, data needs to be save outside the second page either in the MainPage or in isolated storage or using PhoneApplicationService class.
PhoneApplicationService Class
PhoneApplicationService class is defined in Microsoft.Phone.Shell namespace. Instance of PhoneApplicationService is created in standard App.xaml file.
Let's write code:
Step 1: Add a TextBlock inside grid in the MainPage.xaml
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBlock Text="Navigate to 2nd Page" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="0 34" ManipulationStarted="OnTextBlockManipulationStarted" /> </Grid>
Step 2: Place below code in the codebehind i.e. MainPage.xaml.cs
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using System.Windows.Navigation;
namespace Windows_Phone_7_Pass_Data { public partial class MainPage : PhoneApplicationPage { // Constructor public MainPage() { InitializeComponent(); }
void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs args) { this.NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative)); args.Complete(); args.Handled = true; } } }
Step 3: Add a new page SeconPage.xaml and add a TextBlock inside in the SecondPage.xaml
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBlock Text="Navigate to 1st Page" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="0 34" ManipulationStarted="OnTextBlockManipulationStarted" /> </Grid>
Step 4: Add below code in the codebehind i.e. SecondPage.xaml.cs
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using System.Windows.Navigation; using Microsoft.Phone.Shell;
namespace Windows_Phone_7_Pass_Data { public partial class SecondPage : PhoneApplicationPage { Random rand = new Random(); public SecondPage() { InitializeComponent(); }
protected override void OnManipulationStarted(ManipulationStartedEventArgs args) { ContentPanel.Background = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(255), (byte)rand.Next(255),(byte)rand.Next(255))); base.OnManipulationStarted(args); }
protected override void OnNavigatedFrom(NavigationEventArgs args) { if (ContentPanel.Background is SolidColorBrush) { Color clr = (ContentPanel.Background as SolidColorBrush).Color; PhoneApplicationService.Current.State["Color"] = clr; } base.OnNavigatedFrom(args); }
protected override void OnNavigatedTo(NavigationEventArgs args) { // Retrieve color if (PhoneApplicationService.Current.State.ContainsKey("Color")) { Color clr = (Color)PhoneApplicationService.Current.State["Color"]; ContentPanel.Background = new SolidColorBrush(clr); } base.OnNavigatedTo(args); }
void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs args) { this.NavigationService.GoBack(); args.Complete(); args.Handled = true; } } }
Overrided method OnNavigatedFrom contains PhoneApplicationService, state property of PhoneApplication service is used to save and restore data. State property in PhoneApplicationService is dictionary which is of type IDictonary<string, object>. It preserves the data only when application is running, it should not be used when data needs to be preserved between multiple execution of a program.
State can store only serializable object. The object must have public parameterless constructor and all the properties should be serializable or of types that have Parse methods to convert strings to objects.
Overrided method OnNavigatedTo method will get the color from the key if key exists. The key will not exist when SecondPage is navigated first time, there after the page will retain the last color set.
Isolated Storage
Isolated storage is much like disk storage. Windows Phone 7 application has access to isolated storage using System.IO.IsolatedStorage but only to files that application itself has created. Isolated storage can be used to save data between multiple executions. It can be used to save application settings or whole file can be read and written in isolated storage.
Open App.xaml and you will get below code.
<shell:PhoneApplicationService Launching="Application_Launching" Closing="Application_Closing" Activated="Application_Activated" Deactivated="Application_Deactivated"/>
PhoneApplicationService object is created by App.xaml and assigns event handlers to four events.
The Launching event triggers when the program is first executed from start screen.
The Closing event triggers when the program is really terminated, like pressing back button.
The Activated event triggers when the program is restored from tombstoning.
The Deactivated event triggers when the program is tombstoned.
So, when program starts, Launching or Activaged event triggers based on whether it is being started from Start screen or coming out of tombstoned. Similary when program ends, Closing or Deactivated event triggers based on whether it is terminated or tombstoned.
A program should load application setting on Launching or Activated event and save it on Closing or Deactivated event. The application setting needs to be saved in Deactivated event as we never know whether it will be restored or not. If restored it should load with last applciation settings.
Let's write code:
Step 1: Add a property in App.xaml.cs
public Brush BackgroundBrush { set; get; }
Step 2: Add SaveSettings in Closing and Deactivted methods and LoadSettings in Launching and Activated events
// 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(); }
Step 3: Add LoadSettings and SaveSettings method in App.xaml.cs
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(); } }
Above methods obtains IsolatedStorageSettings which is Dictionary object. SaveSettings saves the Color property of BackgroundBrush in isolated storage and LoadSetting loads the color from isolated storage.
While loading TryGetValue needs to be used which returns true if key exists.
Step 4: Add below code in the MainPage.xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using Microsoft.Phone.Controls; using System.Windows.Navigation; using Microsoft.Phone.Shell;
namespace Windows_Phone_7___Isolated_Storage { public partial class MainPage : PhoneApplicationPage { Random rand = new Random(); int numTaps = 0; PhoneApplicationService appService = PhoneApplicationService.Current; public MainPage() { InitializeComponent(); UpdatePageTitle(numTaps);
// Access App class for isolated storage setting Brush brush = (Application.Current as App).BackgroundBrush; if (brush != null) { ContentPanel.Background = brush; } }
protected override void OnManipulationStarted(ManipulationStartedEventArgs args) { SolidColorBrush brush = new SolidColorBrush(Color.FromArgb(255, (byte)rand.Next(256), (byte)rand.Next(256), (byte)rand.Next(256))); ContentPanel.Background = brush; // Save to App class for isolated storage setting (Application.Current as App).BackgroundBrush = brush; 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; base.OnNavigatedFrom(args); }
protected override void OnNavigatedTo(NavigationEventArgs args) { // Load numTaps if (appService.State.ContainsKey("numTaps")) { numTaps = (int)appService.State["numTaps"]; UpdatePageTitle(numTaps); } } } }
Now run the application, click on taps, you will notice that taps count will increase and background color will keep on changing. Now touch the Start button and reach to menu. Start this application again, application will load with last saved color but number of times it is tapped won't be number of times it is tapped earlier, it will start with zero
Tap the taps total again multiple times touch the Start button, now press back button. This time taps number as well as backgroundcolor both will be retained.
This ends the article of retaining data across multiple instance in Windows Phone 7.
|