How to create watermark Textbox in Windows Phone 8

In this tutorial in step by step manner we will learn to create watermark textbox in Windows Phone 8. Watermark textbox looks like below. You use watermark textbox in your app if you want to display readable text to user such that they can enter desired information in that particular textbox. In below app these two watermark textboxes are giving information that user should enter Name and Phone in first and second textboxes respectively.

image

Let us learn how we can create watermark textbox.

Step 1

Create two text boxes and set text property of textboxes as watermark text. Since we want to display Name and Phone as watermark text of two textboxes so we have set Text property as Name and Phone respectively.

 



<TextBox x:Name="txtName"
                     Text="Name"                     
                     GotFocus="txtName_GotFocus" 
                     LostFocus="txtName_LostFocus"
            />
                
            <TextBox x:Name="txtPhone" 
                     Text="Phone"                    
                     GotFocus="txtName_GotFocus"
                     LostFocus="txtName_LostFocus"
             />



I have also set GotFocus and LostFocus events of textboxes.

Step 2

In watermark textbox when user will click on the textbox prepopulated value should get erased and user can type in new value. In Windows Phone 8 for textbox GotFoucs event gets fired when user selects textbox, so on GotFocus we need to perform two tasks,

  1. Erase prepopulated task
  2. In case user has left textbox without putting any value then again set textbox text with previous prepopulated value.

 


        string data;
        private void txtName_GotFocus(object sender, RoutedEventArgs e)
        {

            TextBox t = sender as TextBox;
            data = t.Text;
            t.Text = string.Empty;

        }



In above code snippet we are typecasting as TextBox and then setting its Text property to string.empty. Before setting value to empty we are saving existing text value such that if user leaves textbox control without inserting any value then previous value can be used to prepopulate textbox.

Step 3

Assume that user clicked or touched textbox but did not type any value and went away. In this case pervious value should get prepopulated in textbox. So to do this when user will navigate from control we need to check that whether textbox contains any value. If textbox text is empty then we will set text property to previous value. This can be done as below,

 


   
private void txtName_LostFocus(object sender, RoutedEventArgs e)
        {
            TextBox t = sender as TextBox;
            if (t.Text.Equals(string.Empty))
            {
                t.Text = data;
            }

        }


This is what all you need to do to create watermark textbox in Windows Pone 8. I hope this post is useful. See demo of control below,

XAML Bindings in Windows Phone 8

I thank my friend Suchit Khanna for co-authoring this article with me

Data is an ubiquitous entity in today’s world of application development, present in some form or the other, and your application should have an intuitive UI that is able to bind to data as well as respond to any form of change in it. Well this what you will learn in this chapter how to bind to data in Windows Phone 7, so without any further delay lets jump onto code.

First let us write a model class that would contain information about a student:


public class Student
 {

public string Name { get; set; }

public int Age { get; set; }

public int StudentId { get; set; }

public string SchoolName { get; set; }

}

So you can see here that class student has simple 4 properties that tell about the name, age, student id and school name of a given student.

Next you need to create a UI for this student class so that these properties can be represented on that UI.

Go to MainPage.xaml and divide the content panel grid into two rows, next add a StackPanel control on the first row of the grid and add ListBox on the second row of the grid, so your xaml code should look like:


<!--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="STUDENT LIST" Style="{StaticResource PhoneTextNormalStyle}"/>
 </StackPanel>

<!--ContentPanel - place additional content here-->
 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 <Grid.RowDefinitions>
 <RowDefinition Height="auto"/>
 <RowDefinition />
 </Grid.RowDefinitions>
 <StackPanel Grid.Row="0" DataContext="{Binding ElementName=studentListing, Path=SelectedItem}">

 </StackPanel>
 <ListBox x:Name="studentListing" Grid.Row="1" BorderBrush="WhiteSmoke" BorderThickness="3">

 </ListBox>
 </Grid>
 </Grid>

Do not focus on the DataContext snippet for the time being now, you will come to know about later in chapter.

You need to display the list of students available with you on the UI for which you will make use of ListBox control.

Now comes the interesting part, the student class which you wrote in previous step has many properties and from that in the ListBox control you only want to display the name of the student, so how do you go about implementing this? Well you need to specify the template for the ListBox where you will specify that bind the control in the template which you specified to the name property of the Student:


<ListBox x:Name="studentListing" Grid.Row="1" BorderBrush="WhiteSmoke" BorderThickness="3">
<ListBox.ItemTemplate>
 <DataTemplate>
<TextBlock Text="{Binding Path=Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

As mentioned you specified the ItemTemplate for the ListBox to tell how the ListBoxItems should look like, this case we are using TextBlock control to display each of the items from the list and binding the Text property of the control to Name property of the Student.

Path property tells where to find the data in the Binding object (in your case the Binding object is the Student).

So analogy drawn is that List<student> in the C# code is represented with a ListBox control on UI and we are specifying that bind Text property to Name property of student which represents individual items.

Let us add some code behind file, MainPage.xaml.cs where we create a list of students and show it on ListBox:


IEnumerable<Student> RetrieveStudentsList()
 {
 return new List<Student>()
 {
 new Student{Age = 5, Name = "Akash", SchoolName = "ABC Public School", StudentId = 1},
 new Student{Age = 6, Name = "Sachin", SchoolName = "ABC Public School", StudentId = 2},
 new Student{Age = 10, Name = "Javed", SchoolName = "XYZ Public School", StudentId = 3}
 };
 }

The above function returns a simple collection of 3 student details and now you will pass this to the ListBox:


studentListing.ItemsSource = RetrieveStudentsList();

This line sets the data for ListBox and running your application should result as:

image

So far so good, you displayed the list of students, but now we need to show the details of each of these students.

The stack panel control which we added in the previous step will be used now to show the details of the selected student in the ListBox. Your stack panel control should now look like:


<!--ContentPanel - place additional content here-->
 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 <Grid.RowDefinitions>
 <RowDefinition Height="auto"/>
 <RowDefinition />
 </Grid.RowDefinitions>
 <StackPanel Grid.Row="0" DataContext="{Binding ElementName=studentListing, Path=SelectedItem}">
 <StackPanel Orientation="Horizontal">
 <TextBlock Text="Name : " />
 <TextBlock Text="{Binding Path=Name}" />
 </StackPanel>
 <StackPanel Orientation="Horizontal">
 <TextBlock Text="Age : " />
 <TextBlock Text="{Binding Path=Age}" />
 </StackPanel>
 <StackPanel Orientation="Horizontal">
 <TextBlock Text="School : "/>
 <TextBlock Text="{Binding Path=SchoolName}" />
 </StackPanel>
 </StackPanel>
 <ListBox x:Name="studentListing" Grid.Row="1" BorderBrush="WhiteSmoke" BorderThickness="3">
 <ListBox.ItemTemplate>
 <DataTemplate>
 <TextBlock Text="{Binding Path=Name}" />
 </DataTemplate>
 </ListBox.ItemTemplate>
 </ListBox>
 </Grid>

You will see that the stack panel control does the job of showing the details of the selected student, if you notice the parent stack panel control does the job of binding to the ListBox control:


<StackPanel Grid.Row="0" DataContext="{Binding ElementName=studentListing, Path=SelectedItem}">

Here in binding we have told that the data source for this stack panel is the list box control, which we specified by telling the element name, studentListing is the x:name of our ListBox control.

But this is a collection which we bound to our stack panel, we need to look for a particular item’s details, which we will show in the stack panel, for that we specify the path to be selected Item proeprty of the list box control:

Path=SelectedItem

Now since the selected item is an instance of Student class we have specified binding to properties of the selected student on the textblocks in the stack panel. Now you can press F5 to run the application to see how it looks like:

image

On selecting items on the ListBox we can see details of the same.

This completes the listing of our student.

Binding Image

Let us add over what we have built so far, you can add images to the students details and bind this on UI.

For this go ahead and add a new property to the Student class that we built:


public ImageSource StudentImage { get; set; }

This property will be used to set the image for student; for the sample sake you can write a private function that would return a BitmapImage every time.


private ImageSource GetImage()
 {
 return new BitmapImage(new Uri("student.png", UriKind.Relative));
 }

Let us refactor the xaml code so far to accommodate the new feature we are building , to the image of selected student.

The xaml code on MainPage.xaml file should look like this now:


<!--ContentPanel - place additional content here-->
 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 <Grid.RowDefinitions>
 <RowDefinition Height="auto"/>
 <RowDefinition />
 </Grid.RowDefinitions>
 <Grid Grid.Row="0" DataContext="{Binding ElementName=studentListing, Path=SelectedItem}">
 <Grid.RowDefinitions>
 <RowDefinition />
 <RowDefinition />
 <RowDefinition />
 </Grid.RowDefinitions>
 <Grid.ColumnDefinitions>
 <ColumnDefinition/>
 <ColumnDefinition/>
 </Grid.ColumnDefinitions>
 <StackPanel Orientation="Horizontal" Grid.Row="0">
 <TextBlock Text="Name : " />
 <TextBlock Text="{Binding Path=Name}" />
 </StackPanel>
 <StackPanel Orientation="Horizontal" Grid.Row="1">
 <TextBlock Text="Age : " />
 <TextBlock Text="{Binding Path=Age}" />
 </StackPanel>
 <StackPanel Orientation="Horizontal" Grid.Row="2">
 <TextBlock Text="School : "/>
 <TextBlock Text="{Binding Path=SchoolName}" />
 </StackPanel>
 <Image Grid.RowSpan="3" Height="100" Grid.Column="1" Source="{Binding Path=StudentImage}" />
 </Grid>

The only difference you see this time from previous code being that we have laid out the UI in a nested Grid instead of the Stack Panel and added a new Image control which bound to the new Property you created in the Student class:


<Image Grid.RowSpan="3" Height="100" Grid.Column="1" Source="{Binding Path=StudentImage}" />

Run the application to see the output:

image

You can see that we have achieved binding an image to our application for student details.

XML binding

In this section we will take an example of how to parse an xml and display it on UI, the task is to built an application that would teach a new word every day to the user.

For this you are given an rss feed of yahoo: http://xml.education.yahoo.com/rss/wotd/

You need to parse the rss feed which is an xml file and show the data on UI.

Create new project named ‘WordOfDay’ ; next the go to your xaml page add the following code:


<!--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="Word Of the Day" Style="{StaticResource PhoneTextNormalStyle}"/>
 <TextBlock x:Name="txtWord" Text="{Binding Title}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle2Style}"/>
 </StackPanel>

<!--ContentPanel - place additional content here-->
 <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
 <Grid.RowDefinitions>
 <RowDefinition Height="Auto" />
 <RowDefinition />
 </Grid.RowDefinitions>
 <StackPanel Orientation="Horizontal">
 <TextBlock Text="Date Published : " />
 <TextBlock x:Name="txtPublishDate" />
 </StackPanel>
 <TextBlock Grid.Row="2" x:Name="txtSummary" />
 </Grid>
 </Grid>

There is nothing much complicated here, the real work happens in the code behind file:

First we need to add reference to the System.ServiceModel.Syndication which should be found at:

C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client

Now after adding the reference, add following code :


private readonly WebClient _webClient;

// Constructor
 public MainPage()
 {
 InitializeComponent();
 _webClient = new WebClient();
 _webClient.DownloadStringCompleted += OnWebClientDownloadStringCompleted;
 _webClient.DownloadStringAsync(new Uri("http://xml.education.yahoo.com/rss/wotd/"));
 }

private void OnWebClientDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
 {
 var rssFeed = e.Result;
 ParseFeed(rssFeed);
 }

private void ParseFeed(string _rssFeed)
 {
 if (string.IsNullOrEmpty(_rssFeed))
 MessageBox.Show("Could not retrieve the data...");
 else
 {
 XmlReader reader = XmlReader.Create(new StringReader(_rssFeed));
 SyndicationFeed feed = SyndicationFeed.Load(reader);

var iterator = feed.Items.GetEnumerator();
 SyndicationItem item = null;

if (iterator.MoveNext())
 item = iterator.Current;

if (item != null)
 {
 txtWord.Text = item.Title.Text;
 txtSummary.Text = item.Summary.Text;
 txtPublishDate.Text = item.PublishDate.Date.ToString();
 }
 }
 }

&nbsp;

The WebClient instance helps to download the rss feed from the given uri, the call: DownloadStringAsync(..) is a asynchornous call so we need to subscribe to DownloadStringCompleted event where we read read the result received from the feed.

On the callback function the result is parsed with the help of ParseFeed(…) function which reads the string using XmlReader and the .NET framework for Windows Phone comes with the SyndicationFeed class which helps to read and interpret any rss feed.

Next you iterate over the syndication feed to get individual syndication items and read the title/summary/publish date of each of these syndication items.

Press F5 and you should see the application running:

image

So here we go, we have successfully read a rss feed and displayed it on the UI, thus creating our word of the day application.

In this way you can work with XAML bindings in Windows Phone 8. I hope you find this post useful. Thanks for reading.

Getting Started with Windows Phone 8

Much awaited Windows Phone 8 SDK got launched on 30th October 2012. And as all we expected there is HTML5 support in Windows Phone 8.

image

To get it started navigate here to download Windows Phone 8 SDK and then from the New Downloads section download Windows Phone SDK 8.0. There are two options available to download Web Installer and DVD.


image

Download Windows Phone 8 SDK from there. After downloading start installing it.

 image

After installing you will be asked to restart the system. Click on Restart Now to restart the system

image

 

After successful installation of Windows Phone 8 SDK, you will get confirmation window as following image. Click on launch to launch Visual Studio after installation.

image

Now go ahead and create a Windows Phone Application project. You will notice that there is template for Windows Phone HTML5 App. However let us go ahead and create an application using Windows Phone App Template.

image 
Next you will be asked to choose the OS version. Choose Windows Phone OS 8.0 here.

image

Let us go ahead and put a Text Block on the MainPage.xaml.

image 

In Windows Phone 8 SDK you got 4 types of emulator to run and test the application. Select Emulator WVGA 512MB and run the application in emulator

image

On running the application, you will see all new emulator. In further post we will discuss more on new features of emulator.

image

So now we are all set to explore more on Windows Phone 8 . In further posts we will go in detail of each new features and API. I hope you find this post useful. Thanks for reading.

ASP.Net Web API Service in Windows Phone: Part 4 of Many

Creating First HTTP Service using ASP.NET Web API: Part1 of Many

Consuming ASP.NET Web API Service using HttpClient: Part2 of Many

How to Self-Host ASP.Net Web API: Part 3 of Many

In this post we will consume ASP.Net Web API HTTP Service in Windows Phone Application. If you do not specify header information in HTTP request then by default ASP.Net Web API service returns JSON data. So essentially there are three steps involved in consuming HTTP Service from ASP.Net Web API in Windows Phone Application.

  1. Make a HTTP Request
  2. Read data from HTTP Response
  3. Parse returned JSON data and bind data to data bound control

In this post we are going to consume service created in this POST

I have created a Windows Phone Application by choosing target framework 7.1. We are going to display Bloggers Data returned from ASP.Net Web API service in a ListView. Essentially we are going to consume a JSON Data from a HTTP Service. For that add below references in the project.

image

We are going to de-serialize JSON data using DataContractJsonSerializer class. We need to create a class at client side representing Bloggers entity from the service. Let us create a class called BloggersClient. We will de-serialize JSON data returning from the HTTP service in this object of this class.


namespace WindowsPhoneClient
{
public class BloggersClient
{
public string Id { get; set; }
public string Name { get; set; }
public string AreaOfIntrest { get; set; }

}
}

Once the client class is in placed add following references,

image

We are going to download JSON data from ASP.Net Web API service using WebClient class. Make sure that you are passing URL of your HTTP Service.

image

In the completed event, we will parse returned JSON using DataContractJsonSerializer class. In following code,

  • Creating MemoryStream form returned result
  • Creating object to de-serialize the returned JSON data
  • Reading de-serialized data object in List of BloggersClient
  • Setting List of BloggerClient as ItemSource of ListBox. On the XAML we have put a ListBox with name lstBloggers.

image

Code behind to load data from ASP.Net Web API HTTP Service on page load of the application and s display in ListBox is as following


using System;
using System.Collections.Generic;
using System.Net;
using Microsoft.Phone.Controls;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Text;

namespace WindowsPhoneClient
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
WebClient proxy = new WebClient();
proxy.DownloadStringCompleted +=
new DownloadStringCompletedEventHandler(proxy_DownloadStringCompleted);
proxy.DownloadStringAsync(new Uri("http://localhost:39192/api/Bloggers"));
}

void proxy_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
Stream s = new MemoryStream(Encoding.Unicode.GetBytes(e.Result));
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(List<BloggersClient>));
List<BloggersClient> result = (List<BloggersClient>) ser.ReadObject(s);
lstBloggers.ItemsSource = result;
}
}
}

On the XAML, we have put ListBox control do bind data from HTTP Service in the control.

If you are not aware of Data Binding in ListBox then watch a quick Video here


<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="ASP.Net Web API" 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">
<ListBox x:Name="lstBloggers">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" Style="{StaticResource PhoneTextTitle2Style}" />
<TextBlock Text="{Binding AreaOfIntrest}" Style="{StaticResource PhoneTextAccentStyle}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>

Now press F5 to run the application. You should able to get Bloggers detail from ASP.Net Web API service in Windows Phone Application.

image

I hope you find this post useful. Thanks for reading.

Video : ListBox Data Binding in Windows Phone


using System.Collections.Generic;
using Microsoft.Phone.Controls;

namespace PhoneApp1
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.DataContext = GetProducts();
}

private List<Product> GetProducts()
{
List<Product> lstProduct = new List<Product>
{
new Product { ProductName ="Pen" , ProductCat ="Education" , ProductPrice = 100 },
new Product { ProductName ="Pencil" , ProductCat ="Education" , ProductPrice = 200 },
new Product { ProductName ="Bat" , ProductCat ="Sports" , ProductPrice = 400 },
new Product { ProductName ="Ball" , ProductCat ="Sprots" , ProductPrice = 90 },
new Product { ProductName ="Eraser" , ProductCat ="Education" , ProductPrice = 10 },
new Product { ProductName ="Shoes" , ProductCat ="Sports" , ProductPrice = 790 },
new Product { ProductName ="NoteBook" , ProductCat ="Education" , ProductPrice = 345 },
new Product { ProductName ="Cycle" , ProductCat ="Sports" , ProductPrice = 5000 },
new Product { ProductName ="Gel Pen" , ProductCat ="Education" , ProductPrice = 130 },
new Product { ProductName ="Football" , ProductCat ="Sports" , ProductPrice = 440 },
new Product { ProductName ="Hockey Stick" , ProductCat ="Sports" , ProductPrice = 320 },
new Product { ProductName ="Drwaing  Book" , ProductCat ="Education" , ProductPrice = 480 },
new Product { ProductName ="Novel" , ProductCat ="Education" , ProductPrice = 180 },
new Product { ProductName ="Tenis Bat" , ProductCat ="Sports" , ProductPrice = 340 },
new Product { ProductName ="Tenis Ball" , ProductCat ="Sports" , ProductPrice = 46 }

};
return lstProduct;

}
}

public class Product
{
public string ProductName { get; set; }
public string ProductCat { get; set; }
public int ProductPrice { get; set; }
}
}


<ListBox x:Name="lstProduct" ItemsSource="{Binding}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding ProductName}" Style="{StaticResource PhoneTextTitle2Style}" />
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding ProductCat}" Style="{StaticResource PhoneTextNormalStyle}" />
<TextBlock Text="{Binding ProductPrice}" Style="{StaticResource PhoneTextAccentStyle }" />
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Video : Find which Panorma Item is selected in Windows Phone

 

Source Code


public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();

myPanorma.SelectionChanged += new EventHandler<SelectionChangedEventArgs>(myPanorma_SelectionChanged);
}

void myPanorma_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (myPanorma.SelectedIndex == 0)
{
MessageBox.Show("first item is selected");
}
if (myPanorma.SelectedIndex == 1)
{
MessageBox.Show("second item is selected");
}

}

Windows Phone Application Life Cycle and Fast Application Switching

What we will learn in this Article ?

  • Windows Phone terminology
  • Application Life Cycle
  • Fast Application Switching
  • Managing Page State

Windows Phone Terminologies

Application State

Application sate is application level Data. This Data may be returned by the service and being displayed in different view. For example a list of students being retuned by a service and on Page1 only students names are being displayed whereas on Page2 student names and age are being displayed. So Application State is a data returned by service and being displayed differently on different pages of the application.

Page State

It is common scenario that user fill some value on page and navigate from that page. On returning to the same page user expects persisted value on the page. Page state is visual persisted state of the page. For example on a page there is one text box and one check box. User has entered some value in text box and checked the check box. Value entered in the textbox and checked checkbox creates Page state of the page.

Tombstoning

It is process to persist data after application is terminated. Data can be persisted of an individual page or data can be persisted of state of whole application. When again user navigates back then application gets recreated and all the data persisted gets restored.

State Dictionary

Dictionary objects are used to store key/value pair. Dictionary in Windows phone is used to restore the Application state. At time of Tombstoning Dictionary gets preserved.

Application Life Cycle

Application life cycle of Windows Phone application says about different state of the application from launching to closing. User launches an application and application goes to running state. Due to launching of other application or on pressing of hardware start or search button application goes to dormant or tombstone state. Again on the launching of application, app gets activated from either dormant or tombstone state. Application can be closed by pressing of hardware back button.

Block diagram on Application Life Cycle events

image

Different events are as below. All events are written in App.Xaml.CS

Application Launching

clip_image002

Application Activated

clip_image004

Application Deactivated

clip_image006

Application Closing

clip_image008

As a developer it is must to have understanding of sequence of events get executed in Windows Phone application life cycle

Fast Application Switching

Windows Phone 7.5 operating system provides improved fast application switching over Windows Phone 7 operating system. Before we go into details of how FAS is better in Mango, let us first understand what is FAS?

Imagine application “A” is running and user launches a new application “B”. On pressing hardware back button user can return back to application “A”. If application “A” gets activated without “resuming “ screen then it can be termed as “ Fast Application Switching

In Windows Phone 7.5 version FAS is improved over Windows Phone 7 with introduction of new state in application life cycle called “Dormant state”. Whereas in Windows Phone 7.0 version there was no Dormant state and on deactivation application directly goes to Tombstone state.

In Windows Phone 7 flow of application was as below,

  • User deactivates application by pressing hardware start or search button
  • Application goes to tombstone state
  • Windows Phone 7 operating system saves information about application Navigation state and State Dictionary
  • Operating system terminates application thread and processes.
  • User again activates application by pressing hardware back button.
  • Operating system creates application thread and process.
  • Operating system restores memory state by retrieving saved value of Navigation state and state dictionary.

Due to above steps in Windows Phone 7 operating system user gets feeling that application was running in background and got resumed from there. However this is not true and operating system again creates application process and restores memory state. Creation of application process and restoration of application memory states take time and cause to slower application switching.

image

In Windows Phone 7.5 flow of application is as below,

  • User deactivates application by pressing hardware start or search button
  • Application goes to dormant state
  • Windows Phone 7.5 operating system preserve instance of the application
  • User again activates application by pressing hardware back button.
  • Operating system restores preserve instance and re activate application
  • If operating system runs low on the memory, it pushes application from dormant state to tombstone state.
  • If application is reactivating from tombstone state then it follows the same cycle as of Windows Phone 7 operation system.

image

Now you understand significant of dormant state for Fast Application switch. With introduction of dormant state in application life cycle, operating system preserve instance of the application in memory unless it is forced to release due to low memory. So at the time of application reactivation as a developer you need to check whether to restore the application or not? If application is reactivating from dormant state then there should not be restoration.

On Application Activated event you can check whether application is reactivating from dormant or tombstone state as below,


private void Application_Activated(object sender, ActivatedEventArgs e)
 {

if (e.IsApplicationInstancePreserved)
 {

// No need to restore the application.
 // Application is reactivating from dormant state
 }

else
 {
 // Need to restore the application.
 // Application is reactivating from tombstone state
 // Read state dictionary and Navigation state to restore memory state

}
 }

An Application gets closed by pressing hardware back button. And in that case application neither goes to dormant state or tombstone state. If there are multiple pages in application then user navigates between pages using hardware back button. However if on start page of application user press hardware back button then operating system will close the application. While closing application Application_Closing() events gets executed.

Maintaining Page State

Page state deals with transient data whereas Application State deals with Persistent Data.

Page state deals with preserving data binding of the user interface of the page. If application is reactivating from dormant state then there is no need of preserving the state of the page or in simple words data of the controls on page explicitly. However if application is reactivating from tombstone state then page data need to be preserved and restore explicitly.

To demonstrate how Page State works? I have designed page as below,

Let us put some control on the phone application page.

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

 <TextBox x:Name="txtValue" Height="100" Margin="12,37,58,470" />
 <CheckBox x:Name="chkValue" Height="100" Margin="251,144,0,364"
 HorizontalAlignment="Left" Width="134" />
 <Slider x:Name="sldValue" Value="30"
 Height="100" Margin="28,383,58,124" />

 </Grid>

There are three controls on the page. After tombstone, we need to preserve and restore value of these controls. Now we need to create properties for each control. We need to call NotifyPropertyChanged event in the setter of property to notify when value changed at the control. Control value would be bind with two ways binding with these properties. Eventually Data class will be as below,


&nbsp;

using System.Runtime.Serialization;
using System.ComponentModel;

namespace RestorePageState
{
 [DataContract]
 public class Data : INotifyPropertyChanged
 {

private string textValue;
 private bool chckValue;
 private double sliderValue;

public string TextValue
 {
 get
 {
 return textValue;

}
 set
 {
 textValue = value;
 NotifyPropertyChanged("TextValue");

}
 }

public bool ChckValue
 {
 get
 {
 return chckValue;

}
 set
 {
 chckValue = value;
 NotifyPropertyChanged("ChckValue");

}
 }
 public double SliderValue
 {
 get
 {
 return sliderValue;

}
 set
 {
 sliderValue = value;
 NotifyPropertyChanged("SliderValue");

}
 }
 public event PropertyChangedEventHandler PropertyChanged;
 private void NotifyPropertyChanged(string propertyName)
 {
 if (null != PropertyChanged)
 PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
 }

}
}

With Data Class in place we need to preserve state of the page. There are two checks to perform before preserving page state. First check to be done, whether application is reactivating from dormant state. If so then there is no need of restoring the state. To save the state of the page OnNavigatedFrom method instance of the Data need to be saved in the State dictionary as below,


protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
 {
 if (e.NavigationMode != System.Windows.Navigation.NavigationMode.Back)
 {
 State["Data"] = dataToBindControls;
 }
 }

In above code dataToBindControls is object of Data bind to the controls on the page. To restore the page OnNavigatedTo method state count need to checked as below.


protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
 {
 if (isNewInstanceofPage)
 {
 if (dataToBindControls == null)
 {
 if (State.Count > 0)
 {
 dataToBindControls = (Data)State["Data"];
 }
 else
 {
 dataToBindControls = new Data();
 }
 }
 DataContext = dataToBindControls;
 }
 isNewInstanceofPage = false;
 }

}

Essentially there are three tasks we are performing in above function

  • Checking if it is new instance of the page.
  • If yes then checking if value of data control [object of data class ] is null
  • If null then reading from the state else creating new instance of that.

Full source code behind to preserve page is as below,

using Microsoft.Phone.Controls;

namespace RestorePageState
{
 public partial class MainPage : PhoneApplicationPage
 {

 Data dataToBindControls;
 bool isNewInstanceofPage;

public MainPage()
 {
 InitializeComponent();
 isNewInstanceofPage = true;
 }

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
 {
 if (e.NavigationMode != System.Windows.Navigation.NavigationMode.Back)
 {
 State["Data"] = dataToBindControls;
 }
 }

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
 {
 if (isNewInstanceofPage)
 {
 if (dataToBindControls == null)
 {
 if (State.Count > 0)
 {
 dataToBindControls = (Data)State["Data"];
 }
 else
 {
 dataToBindControls = new Data();
 }
 }
 DataContext = dataToBindControls;
 }
 isNewInstanceofPage = false;
 }

}
}

Last but not least data need to be bind to controls as below,


<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

 <TextBox x:Name="txtValue" Height="100" Margin="12,37,58,470"
 Text="{Binding TextValue,Mode=TwoWay}"/>
 <CheckBox x:Name="chkValue" Height="100" Margin="251,144,0,364"
 HorizontalAlignment="Left" Width="134"
 IsChecked="{Binding ChckValue,Mode=TwoWay}"/>
 <Slider x:Name="sldValue"
 Height="100" Margin="28,383,58,124"
 Value="{Binding SliderValue,Mode=TwoWay}"/>

 </Grid>

In this way a page state can be preserved. Before debugging last step we need to perform is enable Tombstone upon deactivation while debugging in the properties page. There may be other approach to preserve state as below,

  • Creating extension method for page class
  • Create helper class and call method of the class to save control’s data.

I will conclude with supporting above approach of Page State restore and retrieve for better encapsulation. Since each page is handling their own state so it is easy to separate the concern for pages individually.