Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Phone

Windows Phone 7 Execution Model : Navigating Between Pages with State

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
7/9/2011 5:31:52 PM

1. Problem

You have to navigate between pages, and you want to store a complex object that is not suitably stored via the query string method. You need to store the object to prevent tombstoning.

2. Solution

You should use the State dictionary provided by the PhoneApplicationService class.

3. How It Works

Sometimes you have to share data between pages that is not suitable for the QueryString property—for instance, when you have to provide a complex object such as an array or list to another page. Moreover, the QueryString property can accept up to 65,519 characters from the Uri object.

Windows Phone 7 helps developers via the State dictionary, which is provided by the PhoneApplicationService class included in the Microsoft.Mobile.Shell namespace.

The PhoneApplicationService class includes the Current static property that retrieves the PhoneApplicationService object related to the current application. By using this object, you can use the State property to store data across pages. Moreover, the PhoneApplicationService automatically manages the application's idle behavior and the application's state when it becomes either active or inactive.

Indeed, managing active and inactive states is an important aspect of Windows Phone 7 life-cycle application management that a developer has to consider. During the application usage, a lot of external events may occur, and the developer has to provide the right solutions to avoid a bad user experience. For example, imagine that a user is filling in a form on the page you provided when that user remembers an important e-mail that needs to be sent immediately. The user presses the hardware Start button, and your application becomes inactive. After the e-mail is sent, the user presses the hardware Back button until the application becomes active again. How would the user react if all data in the form was lost?

To provide a complex object to another page, you could use the global application variable technique too (see Recipe 2-3). But what is provided here for free is tombstoning management. When the application is deactivated because of an external event such as the hardware Start button being pressed, the State dictionary is serialized and stored automatically by the Windows Phone 7 operating system. If the application is activated again—not by launching the application from the Start menu but by going back via the hardware Back button—the State dictionary is deserialized and provided to the application. That's why the State dictionary has to contain only serializable objects.

As already stated in Recipe 2-1, when the Navigate method is called, a brand new page is created and shown. So if your text boxes are blank by default, when the application is activated from the Windows Phone operating system, the page will show empty text boxes.

To manage this aspect and avoid this application behavior, you can implement the code in the OnNavigatedFrom and the OnNavigatedTo event handlers provided by the PhoneApplicationPage class. The OnNavigatedFrom event is raised just before the user is going to navigate off the page. This event handler is the right place to insert the code that saves your data. The OnNavigatedTo event is raised just after the page is shown because of navigation either from another page or from the Windows Phone 7 operating system.

Both event handlers provide a NavigationEventArgs object that provides some interesting properties such as the Uri of the target page or the target application, and the target Content object. For example, in the OnNavigatedFrom event handler, the Content property contains the MainPage object when you come back to the starting page from page 2. On the other hand, when the application is deactivated, the Content property is null and the Uri is set to the app://external/ value.

Another useful property provided by the PhoneApplicationPage class is State. Do not confuse this with the one provided by the PhoneApplicationService class. The one provided by the page is not shared through the application but is for the page only. This is great for storing page data such as text-box values, check-box selections, and so on.

4. The Code

To demonstrate navigation between pages with a complex data object exchanged, we will create a new Windows Phone 7 Silverlight application called NavigatingWithStateApp. In this application, MainPage will show a message taking the first name, last name, and city strings provided by the Page2 page. Those strings are defined in a new class called Person.

using System;

namespace NavigatingWithStateApp
{
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string City { get; set; }

public Person() { }
}
}

The class must be serializable and must provide a public parameterless constructor (if you don't specify it, the compiler will create it for you).

In MainPage.xaml, we added a TextBlock control to show the message, and a hyperlink button to navigate to the second page.

. . .
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock x:Name="tbMsg" />
<HyperlinkButton x:Name="hlNavigate" Content="Navigate to Page 2"
Click="hlNavigate_Click"/>
</Grid>
. . .


In the MainPage.xaml.cs source code, we added the Loaded event handler, which builds the string to be shown only when the State dictionary returned by the PhoneApplicationService's Context property contains the Person object saved in the Page2.

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
if (PhoneApplicationService.Current.State.ContainsKey("Person"))
{
Person p = (Person)PhoneApplicationService.Current.State["Person"];

tbMsg.Text = string.Format("Welcome {0} {1} from {2}", p.FirstName,
p.LastName, p.City);
}
}


As already done in previous recipes, we add another page called Page2.xaml. In the Page2.xaml page, we add three TextBox controls and one Button control:

. . .
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBox x:Name="txtName" Text="FirstName" GotFocus="txt_GotFocus" />
<TextBox x:Name="txtLast" Text="LastName" GotFocus="txt_GotFocus" />
<TextBox x:Name="txtCity" Text="City" GotFocus="txt_GotFocus" />
<Button x:Name="btnSave" Content="Save" Click="btnSave_Click" />
</StackPanel>
</Grid>
. . .


Every TextBox control implements GotFocus, so when the TextBox receives the focus, it will select its own text:

private void txt_GotFocus(object sender, RoutedEventArgs e)
{
TextBox txt = sender as TextBox;
txt.SelectAll();
}

This technique is done to avoid using labels; by showing the string, the text box indicates what its content should be.


The Save button calls the SaveOrUpdate method, which stores the text boxes' text into a Person object. First, the method checks whether the State dictionary of Page2 already contains a Person object. If it does, the method retrieves the object and changes its value. Otherwise, the method creates a brand new object, filling it with the text boxes' values. In both cases, the last instruction is used to store the Person object in the State dictionary of Page2.

Only when the SaveOrUpdate method is called via the Save button is the State dictionary (provided by the Context property of the PhoneApplicationService)populated with the Person object. In this way, the main page will show the message only when the user saves data. If you don't separate the two State dictionaries, and use the PhoneApplicationService's one to store text-box values both on a save operation and on tombstoning, you will have to implement a technique to know when MainPage has to manage data and when it does not.

private void SaveOrUpdate(bool isSaved)
{
Person p = null;

if (this.State.ContainsKey("Person"))
{
p = (Person) this.State["Person"];
p.FirstName = txtName.Text;
p.LastName = txtLast.Text;
p.City = txtCity.Text;
}
else
{
p = new Person();
p.FirstName = txtName.Text;
p.LastName = txtLast.Text;
p.City = txtCity.Text;
}

if (isSaved)
{
PhoneApplicationService.Current.State["Person"] = p;
}

this.State["Person"] = p;
}

The core of this example is the code in the OnNavigatedFrom and OnNavigatedTo event handlers. In the former, the SaveOrUpdate method is called again so that when the application is deactivated, the user doesn't lose data. The method will not be called when the user presses the hardware Back button, because in this case its behavior is similar to the Cancel button in a dialog box. Retrieving when the hardware Back button is pressed is accomplished by checking the Content property of the NavigationEventArgs object passed to the event handler.

protected override void
OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
if (e.Content == null)
{
SaveOrUpdate(false);
}

base.OnNavigatedFrom(e);
}

In the OnNavigatedTo event handler, we simply check whether the State dictionary from the Page2 class contains the Person object and then we eventually fill the text boxes' text with its values.

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs
e)
{
if (this.State.ContainsKey("Person"))
{
Person p = (Person)this.State["Person"];
txtName.Text = p.FirstName;
txtLast.Text = p.LastName;
txtCity.Text = p.City;
}

base.OnNavigatedTo(e);
}


Finally, the Save button code calls the SaveOrUpdate method, passing a true value to indicate that it will have to save the Person object into the PhoneApplicationService's State dictionary.

private void btnSave_Click(object sender, RoutedEventArgs e)
{
SaveOrUpdate(true);
this.NavigationService.GoBack();
}

5. Usage

From Visual Studio 2010, run the application after checking that the target is set to Windows Phone 7 Emulator. The main page will be shown briefly with just the link to navigate to the second page (see Figure 1).

Figure 1. The NavigatingWithStateApp application's first page

By pressing the hyperlink button, you go to the second page, shown in Figure 2.

Figure 2. The second page contains three text boxes and a button.

Now you can insert your credentials and press the Save button so the application returns to the start page and shows the message (see Figure 3).

Figure 3. The main page greets the person you added from the page 2 form.

Now let's play a bit with the application and explore unexpected situations. Comment the code of the OnNavigatedFrom event handler from Page2.xaml.cs and restart the application. Go to page 2 and add some text to the text boxes. Press the hardware Start button, leaving the application, and then the hardware Back button. The application is resumed, but everything you inserted in text boxes is gone. Now redo the same steps, this time uncommenting the OnNavigateFrom code. The initial situation will be resumed, as you left it.

Other -----------------
- Windows Phone 7 Execution Model : Navigating Between Pages by Using Global Application Variables
- Windows Phone 7 Execution Model : Passing Data Through Pages
- Windows Phone 7 Execution Model : Navigating Between Pages
- Developing for Windows Phone 7 and Xbox 360 : Using the Content Pipeline - Content Importers
- Developing for Windows Phone 7 and Xbox 360 : Using the Content Pipeline - Content Processors
- Developing for Windows Phone 7 and Xbox 360 : Introduction to Custom Effects - Effect States
- Creating a Trial Windows Phone 7 Application
- Deploying the Windows Phone 7 Application on the Device
- Deploying the Application to the Windows Phone 7 Emulator
- Creating a Simple XNA Windows Phone 7 Application
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
 
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server