Published: 18 Feb 2011
By: Xianzhong Zhu
Download Sample Code

In this article, we will delve into how to perform navigation operations between pages as well as passing data in a Silverlight for Windows Phone application.

Contents [hide]

The Windows Phone 7 Silverlight Programming series

  • Part 1 In this article, we will focus upon MultiTouch and manipulation related operations in Silverlight for Windows Phone programming.
  • Part 2 In this article, we will delve into how to perform navigation operations between pages as well as passing data in a Silverlight for Windows Phone application.
  • Part 3 In this article I will introduce to you how to handle XML data in Windows Phone 7 for Silverlight applications.
  • Introduction

    Windows Phone 7 only provides us limited screen space to render UI components. However, as it associates like desktop Silverlight, navigation is still one of the fundamental programming problems in Windows Phone 7 Silverlight development.

    NOTE

    The sample test environments in this article involve:

    1. Windows 7;

    2. .NET 4.0;

    3. Visual Studio 2010;

    4. Windows Phone Developer Tools RTW.

    The NavigationService Class

    Navigation operations between pages in Windows Phone 7 Silverlight mainly depend upon the NavigationService class. As a public and sealed class, NavigationService defines a couple of members. The following tables give their respective definitions and associated explanations.

    Table 1: Properties in class NavigationService

    Properties

    Explanations

    CanGoBack

    Gets a value that indicates whether there is at least one entry in the back navigation history.

    CanGoForward

    Gets a value that indicates whether there is at least one entry in the forward navigation history.

    CurrentSource

    Gets the uniform resource identifier (URI) of the content that is currently displayed.

    Source

    Gets or sets the uniform resource identifier (URI) of the current content or the content that is being navigated to.

    Table 2: Important methods in class NavigationService

    Methods

    Explanations

    GoBack

    Navigates to the most recent entry in the back navigation history, or throws an exception if no entry exists in back navigation.

    GoForward

    Navigates to the most recent entry in the forward navigation history, or throws an exception if no entry exists in forward navigation.

    Navigate

    Navigates to the content specified by the uniform resource identifier (URI).

    StopLoading

    Stops asynchronous navigations that have not yet been processed.

    Table 3: Important events in class NavigationService

    Events

    Explanations

    FragmentNavigation

    Occurs when navigation to a content fragment begins.

    Navigated

    Occurs when the content that is being navigated to has been found and is available.

    Navigating

    Occurs when a new navigation is requested.

    NavigationStopped

    Occurs when the StopLoading method is called, or when a new navigation is requested while the current navigation is in progress.

    There are two things worth noticing. First, the NavigationService class is defined as a read-only public property inside the class Page (which further derives the class PhoneApplicationPage). Refer to the following code:

    Second, as is easily guessed, the most commonly-used member is the method Navigate(), which requires a Uri class parameter, so that we need to package the appropriate target path into a Uri class. Well, let's next look at a simple navigation sample application.

    A Basic Navigation Sample

    There are only two pages first defined in the sample project WP7Navigation. One is MainPage.xaml; the other is Page2.xaml. Let's first look at the related XAML definitions.

    Listing 1: Content definition in MainPage.xaml

    As shown above, in page MainPage we add a HyperlinkButton control which is born as navigation, having a NavigateUri property set to Page2.xaml. So, clicking on HyperlinkButton will automatically navigate to Page2.xaml. The next common Button control, however, does not owe the property NavigateUri, so we need to do something in the code-behind file, as indicated below:

    Quite the same as desktop Silverlight navigation, isn't it? Next, let's look at the Page2.xaml file related stuff.

    Listing 2: Content definition in Page2.xaml

    Also not anything special in the above code! Now, let's continue to look into the code-behind content, as given below.

    First, we make judge whether there are entries in the back navigation history. Note if there is no entry there invoking the GoBack method will result in an exception thrown out. To prove this conclusion, we can change the code in the Main.xaml to the following.

    In the above case, if the click the button "Goto Page 2" (not the link "Click here to enter page 2"), the method btnMain_Click will be executed. However, this will result in a "navigation fail", as shown in Figure 1.

    Figure 1: If there is no entry in the back navigation history invoking the GoBack method would result in an error

    If 

there is no entry in the back navigation history invoking the GoBack method would result in an error

    As is seen, the execution point stops at the special line in the file app.xaml.cs. However, when we start the MainPage and click the Back button from the hard navigation bar, no exception is thrown out. For the inner reason, cute readers can continue to research.

    Apparently, in the Page2 case, we can also utilize the common Navigate method (as indicated in the preceding comments). Things, however, are not simple as imaged. Please read on.

    Difference between GoBack and Navigate

    Well, you may ask: what's the essential difference between the two methods Navigate and GoBack? In fact, whether we use the NavigateUri property of the control HyperlinkButton or the Navigate method of the class NavigationService, the Windows Phone 7 OS will surely create a new instance for the navigate-to page and display it, all of which are done behind the scenes. However, the GoBack method only tries to retrieve the target page through the recent back navigation history and load it – it does not create a new instance of the page.

    Next, let's do something with the running-time application to look at what will really happen.

    Figure 2 gives the first page at the initial running time. Note in there we enter some text into the TextBox control.

    Figure 2: The first page at the initial running time

    The first page at the initial running time

    After that, click the button "Goto Page 2" to navigate to the second page, as shown in Figure 3.

    Figure 3: The second page related snapshot

    The second page related snapshot

    Now, click the button "Goto Page 1" to return to page 1, as shown in Figure 4.

    Figure 4: The text in Page 1 disappears

    The text in Page 1 disappears

    As is noticed, the text in Page 1 disappears. However, instead of clicking the button "Goto Page 1" if you click the hardware navigation button at the bottom most you will notice that the previously-populated text still remains there. The reason for the above results is not difficult to comprehend: clicking the button "Goto Page 1" will invoke the Navigate method of the NavigationService class, which will create a new instance of Page 1, while clicking the hardware navigation button just pops the formerly-generated instance of Page 1 out of the calling stack.

    About the GoForward method

    On the whole, Silverlight for Windows Phone uses the same NavigationService class and page model as the standard Silverlight. However, there seems to be a pity here - the Windows Phone document does not give clear explanation. It seems that Silverlight for Windows Phone supports both back and forward navigation. The fact is, however, the CanGoForward property of the NavigationService class is always False. In Windows Phone invoking GoForward will always throw an exception, because the Windows Phone only support back stack but not forward stack. Hence, if you want to achieve forward navigate in your program, then you have to manually add the corresponding button or menu. MSDN gives a basic Silverlight example concerning the GoForward method; you can make comparison yourselves.

    Well, we've talked so much for the navigation between the pages. Next, we will discuss how to pass data between pages.

    Pass Data between Pages

    On the whole, there are mainly three ways to pass parameters between the pages, i.e. QueryString, global variables and isolated storage. Isolated storage can also be used to share data in the multiple implementation of a program. The principle of isolated storage is quite similar to that in standard Silverlight. We'll cover it in later articles. In this article, we will only delve into the first two approaches.

    The QueryString Way

    The first point to note is, in the related example project WP7Navigation, we've constructed two pages (named DataPassPage1.xaml and DataPassPage2.xaml respectively), as shown in the following figures. For test purpose, we've put a simple TextBox control to hold data in both of the pages.

    Figure 5: Page DataPassPage2.xaml at the initial running time

    Page DataPassPage2.xaml at the initial running time

    Figure 6: Page DataPassPage1.xaml at the initial running time

    Page DataPassPage1.xaml at the initial running time

    Next, let's look at the click event hander of the button btnMain in the page DataPassPage1.xaml, as shown in the following.

    When this program runs the Uri looks like "/DataPassPage2.xaml? InputText = Hello, Windows Phone 7!" It is quite similar to the query string in the HTML form, isn't it? So, if you want to pass multiple parameters, you can use the symbol & to combine them, e.g. "/ DataPassPage2.xaml? InputText = Hello, Windows Phone 7! & Name = Zhu".

    Next, let's take a look at the Click event handler for the button in the page DataPassPage2.xaml, as follows:

    Next, we rewrite the OnNavigatedTo method in the page DataPassPage2.xaml. This virtual method OnNavigatedTo is defined in the Page class, so PhoneApplicationPage also inherits this method. Note the method OnNavigatedTo gets called immediately after the page is created, which means that as soon as the page constructor has finished execution the OnNavigatedTo method is invoked. Another important method is OnNavigatedFrom, which, however, will be triggered as soon as the current page is navigated away.

    Now, let's look at the method OnNavigatedTo implementation in the second page, as follows:

    Note the Page class defines a NavigationContext property of type NavigationContext, which contains a QueryString property of type IDictionary<string, string>. By handling the QueryString property we achieve the target of accepting data passed from page 1. In this case, as soon as we make sure it contains our required data we assign the value corresponding the InputText key to the Text property of the TexBox control. Finally, we trigger the base class OnNavigatedTo method to ensure normal function of the base class.

    In fact, besides the preceding approach, we can also use the following code to achieve the same effect in accepting the passed data.

    Although we can, through the QueryString, pass parameters to a page, we cannot return data. For example, I modify the text in the page 2 as "Windows Phone 7!", and then click the button "Goto Page 1"; we get the initial page 1 appearance. The following figures show this.

    Figure 7: First enter data in page 1

    First enter data in page 1

    Figure 8: First navigate to page 2

    First navigate to page 2

    Figure 9: Then change data in page 2

    Then change data in page 2

    Figure 10: Return to page 1

    Return to page 1

    To solve the above problem, we need to fall back upon global variables.

    Global Variables

    For global variables, we can add to the project a class which can be accessed throughout the entire lifecycle of the program. In this way, we can put the corresponding data in the properties of this class. But now, to do this, we don't have to do extra work. Inherently our project has an existing class to meet this requirement - the App class which inherits from the Application class. Through the Current property of Application we can obtain an instance of the Application class associated with the current program. Since all pages can access the App class in the program, it is the best place to save the data in App, eliminating the trouble of custom implementation. In our case, we add a public InputText property in App.

    Next, let's look at the implementation in Page 1, as listed below.

    In the OnNavigatedTo method, we read the InputText value from the App class, in order that when we change data in page 2 it can be reflected to page 1. Note again the OnNavigatedTo method is activated as soon as the current page (becoming the active page) is called. In the OnNavigatedFrom method we assign the value in the TextBox control to the InputText property in App, for page 2 to read.

    The crucial code in page 2 is as follows:

    As you've seen, the contents are similar to those in page 1. When you again modify the contents in the TextBox control in page 2 and click the "Goto Page 1" button you obtain the required result.

    More about the OnNavigatedTo and OnNavigatedFrom Methods

    First, the names of these two methods are not very good, and even confusing. If OnNavigatedTo is changed to OnNavigatedToThisPageFromOther and OnNavigatedFrom to OnNavigatedFromThisPageToOther things would be clearer.

    Second and the more important is we should make clear when to use the two methods.

    OnNavigatedTo: You can override the OnNavigatedTo method to examine the navigation request and prepare the page for display. For example, you can load the requested data and enable or disable visual elements. Typically, you use the OnNavigatedTo method instead of creating an event handler for the Loaded event. The OnNavigatedTo method is preferable because it is only called once for each time the page becomes active. The Silverlight framework raises the Loaded event each time the element is added to the visual tree, which potentially can happen more than once when activating a page. The OnNavigatedTo method is called for each request, even when the page is retrieved from the cache. You should include in this method code that must be executed for each request, rather than placing that code in the Page constructor.

    OnNavigatedFrom: You can override the OnNavigatedFrom method to perform any actions on the page before it becomes inactive. For example, you can update the data associated with that page. Usually you use the OnNavigatedFrom method, rather than create an event handler for the Navigated event. It is better to use the OnNavigatedFrom method, because you don't have to remove the related event handler from the NavigationService object to avoid object lifetime issues.

    Let's next look at another way for global data access – using the PhoneApplicationService class.

    The PhoneApplicationService Class

    Similar to the App class, we can also store data to be accessed through multiple pages in the State property of the PhoneApplicationService class. State is of type IDictionary<string, object>, so we can save any object, but the only premise is the object should be serializable.

    Joyfully, we do not need to create the PhoneApplicationService instance, through the static property Current an existing PhoneApplicationService instance is ready to use. Note to access the PhoneApplicationService class in the program we need first to add the following namespace reference.

    With the PhoneApplicationService class, we can rewrite page 1, as follows:

    And correspondingly, we can rewrite page 2, as follows:

    Which of the above solutions is the best should rest upon your requirements in the real scenarios.

    Summary

    As pointed at the beginning of this article, navigation still plays a fundamental role in Windows Phone 7 Silverlight programming. And also, transferring data between pages is a key problem. Happily, the two problems are both a piece of cake. OK, hurry to pick up your Silverlight tools to author your fantastic Windows Phone 7 games.

    The Windows Phone 7 Silverlight Programming series

  • Part 1 In this article, we will focus upon MultiTouch and manipulation related operations in Silverlight for Windows Phone programming.
  • Part 2 In this article, we will delve into how to perform navigation operations between pages as well as passing data in a Silverlight for Windows Phone application.
  • Part 3 In this article I will introduce to you how to handle XML data in Windows Phone 7 for Silverlight applications.
  • <<  Previous Article Continue reading and see our next or previous articles Next Article >>

    About Xianzhong Zhu

    I'm a college teacher and also a freelance developer and writer from WeiFang China, with more than fourteen years of experience in design, and development of various kinds of products and applications on Windows platform. My expertise is in Visual C++/Basic/C#, SQL Server 2000/2005/2008, PHP+MyS...

    This author has published 81 articles on DotNetSlackers. View other articles or the complete profile here.

    Other articles in this category


    Displaying Notification Messages in a Silverlight Dashboard Application
    In this article we will see how we could display a notification message and further a list of notifi...
    Develop a Flexible 2.5D Scene Editor Targeting Silverlight RPG Games - Part 1
    Starting from this article, I'm going to introduce to you an excellent 2.5D RPG games scene editor -...
    Develop a Flexible 2.5D Scene Editor Targeting Silverlight RPG Games - Part 2
    In this article, I'm going to introduce to you how to construct such a 2.5D RPG game scene editor th...
    Widget Refresh Timer in MVVM in Silverlight
    In this article we'll see how to refresh and disable widgets using the Model View View-Model pattern...
    Air Space Issue in Web Browser Control in Silverlight
    Air Space issue is a common issue in Web Browser control in Silverlight and WPF. To explain the issu...

    You might also be interested in the following related blog posts


    Why DataBinding With ComboBoxes is NonTrivial read more
    Multi-Page Applications in Silverlight read more
    Apple Safari for Windows and Microsoft Silverlight read more
    MIX07 Slides and Demo Code read more
    Streamline Model-View-Presenter with new StructureMap feature - level 300 read more
    Top
     
     
     

    Please login to rate or to leave a comment.

    Free Agile Project Management Tool from Telerik
    TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.