Thursday, August 25, 2011

Passing Data between Pages in Windows Phone 7


Passing data among pages is something which needs to be given a little care in terms what approach you follow . Since each approach has its own benefits and side effects. I'll try to explain each of them one by one.

For illustration of this concept I've created a sample code which is attached at the end of the article. In this project I've various project each corresponds to one approach which I've described below. Each project has two pages. Touching on the coloured part of one page takes you to another page. First page will display a text string which is provided by the second page. You can simply go to second page add some text into TextBox and you can touch the coloured part to go back to first page which displays the string which you entered on first page.

So here are the approaches one by one:

1. Using Global Variable: This is the easiest and quickest procedure to pass your data among various pages.

Define a "Global Variable" in your App.xaml file as:
public string SecondPageText { get; set; }

After that on your Second page on ManipulationStarted event for the coloured Border use this code:
App.Current as App).SecondPageText = txtBox.Text; // add value to Global variable
NavigationService.GoBack(); // Navigate to first page

PhonePageOne page add this:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
     base.OnNavigatedTo(e);
     txtBlock.Text = (App.Current as App).SecondPageText;
}

2. Using Query String: This procedure is good when we just need to share string based data between two pages.

Add this code in your PhonePageTwo:
private void Border_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
         string uri = "/PhonePageOne.xaml?Text=";
         uri += txtBox.Text;
         NavigationService.Navigate(new Uri(uri, UriKind.Relative));
}

Use this code in your PhonePageTwo:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
  base.OnNavigatedTo(e);
         IDictionary<string, string> parameters = this.NavigationContext.QueryString;
         if (parameters.ContainsKey("Text"))
         {
             txtBlock.Text = parameters["Text"];
         }
}

3. Using PhoneApplicationSerivce States: Every application has a PhoneApplicationService defined Microsoft.Phone.Shell. Each application has one PhoneApplicationService defined in its App.xaml file. We can use this service's property called "State". These "States" are all transient data which means they are available only for one instant of your application which means once you restart your application these states will be lost. Also we should not try to create a new PhoneApplicationService instead we must try to use the service from the current instant. Which can be retrieved using this code:

PhoneApplicationService.Current.State

Now, lets look how can we really use it in our sample.

PhonePageTwo add this code:

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    PhoneApplicationService.Current.State["Text"] = txtBox.Text;
} 
private void Border_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
    NavigationService.GoBack();
}

PhonePageOne add this code:

private void LayoutRoot_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
 NavigationService.Navigate(new Uri("/PhonePageTwo.xaml", UriKind.Relative));
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    if(PhoneApplicationService.Current.State.ContainsKey("Text"))
        txtBlock.Text = (string)PhoneApplicationService.Current.State["Text"];
}

4. Using NextPage intance: Whenever we call "Navigate" using a "/PageOne.xaml" or "/PageTwo.xaml" the OnNavigatedFrom method in current page is called with event arguments with a  Uri property indicating other page and a Content property of type that page (Navigating to) . After that OnNavigatedTo of other page will be called with same arguments. So we have an opportunity to fix the set the value for next page prior to navigating to it. Just take a look at the sample code:

PageTwo add this code:

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedTo(e);
    if (e.Content is PageOne)
    {
        (e.Content as PageOne).txtBlock.Text = txtBox.Text;
    }
} 
private void Border_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
    NavigationService.GoBack();
}

PageOne add this code: (Basically no need to do any thing just use this)

private void LayoutRoot_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
 NavigationService.Navigate(new Uri("/PageTwo.xaml", UriKind.Relative));
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
 base.OnNavigatedTo(e);
}


Source Cod