Part 7 - Understanding the Navigation Model

Sign in to queue

Description

Download the source code for this lesson at http://absolutebeginner.codeplex.com/

Many apps you will want to build require more than one Page, therefore you’ll need to learn how to navigate from one page to another and learn how to pass important data between pages.  Furthermore, you will want to learn how to manipulate the navigation history so that you can control what happens when the user uses the Phone’s physical back button.

Let’s start with the basics.  We’ll create a new Blank App project template called NavigationExample.  Immediately, I’ll add a new Blank Page called Page2.xaml.

Back on the MainPage.xaml, I’ll replace the <Grid> with the following code:

    <StackPanel Margin="30,30,0,0" >
        <TextBlock Text="MainPage.xaml" />
        <Button Content="Go To Page 2"
            Click="Button_Click" />
    </StackPanel>

I’ll right-click the Button_Click event name and select “Go To Definition” to create the event handler method stub.  I’ll add the following code:

// Simple navigation, no parameters
Frame.Navigate(typeof(Page2));

On Page2.xaml, I’ll replace the <Grid> with the following code:

    <StackPanel Margin="30,30,0,0">
        <TextBlock Text="Page2.xaml" />
        <TextBlock x:Name="myTextBlock"
                   Text=""
                   FontSize="32" />
        <Button Content="Go To Page 3"
                Click="Button_Click" />

    </StackPanel>


When I run the app, I can click the button to navigate from the MainPage.xaml to Page2.xaml.

The key to this example is the Frame.Navigate() method.  The Frame object allows you to load and unload Page objects into and out of the viewable area.  Furthermore, it will keep track of the order of pages as they are visited so that you can use methods like GoBack() and GoForward() to traverse the history of pages visited.  In that respect, the Frame is very much like the history feature of your web browser.

In addition to simple navigation, you are able to pass data from one page to the next.  To do this, we’ll add the following code in the Button_Click event of the MainPage.xaml:

          // Simple navigation, no parameters
          //Frame.Navigate(typeof(Page2));

          // Passing a simple type, like a string
          Frame.Navigate(typeof(Page2), "Hola from MainPage");

We’ll retrieve the values that were “sent” via the OnNavigatedToEvent that should already be generated for you in the Page template.  Here’s the code in my version:

    /// <summary>
    /// Invoked when this page is about to be displayed in a Frame.
    /// </summary>
    /// <param name="e">Event data that describes how this page was reached.
    /// This parameter is typically used to configure the page.</param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }

As you can read in the comments, this Page event is invoked when the page is about to be displayed in the Frame.  You can use the input parameter of type NavigationEventArgs to retrieve the value passed from the calling page (if anything was, in fact, passed).  In our case, we’ll add the following code:

myTextBlock.Text = e.Parameter.ToString();

In addition to the OnNavigatedTo() method, there’s also a OnNavigatedFrom()  which will be triggered right before the current page is removed from the Frame.  This might be a good opportunity to clean up any resource or save the current state of the page depending on your needs.

(Note: I also needed to implement the Button_Click event handler method stub on Page2.xaml.  I right-click the name Button_Click on the Page2.xaml and select “Go To Definition”.  This will allow the app to be compiled.)

When I run the app in the emulator, I can see the following when navigating to Page2:

clip_image002

Typically, sending a simple type is not enough.  You may need to send several pieces of information from one page to the next.  To accomplish this, I usually create a class I call NavigationContext that contains the data I need to pass.  I’ll include properties for each data element I may need.

So, I’ll add a new class in my project called NavigationContext.cs and fill it with the following class definition:

    public class NavigationContext
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }

Now, in MainPage.xaml, I’ll add the following code in the Button_Click event handler:

            // Simple navigation, no parameters
            //Frame.Navigate(typeof(Page2));

            // Passing a simple type, like a string
            //Frame.Navigate(typeof(Page2), "Hola from MainPage");

            // Passing an instance of a 'Navigation Context' object
            NavigationContext nav = new NavigationContext()
            {
                ID = 7,
                Name = "Test",
                Description = "This is a test"
            };

            Frame.Navigate(typeof(Page2), nav);

And then in the OnNavigatedTo event handler of the Page2.xaml.cs page:

            //myTextBlock.Text = e.Parameter.ToString();

            var nav = (NavigationContext)e.Parameter;
            myTextBlock.Text = nav.Description;

Now, when I navigate from the MainPage to Page2, I see the following:

clip_image004

Finally, I want to show you how you can manipulate the Frame’s history.  I’ll add a third page called Page3.xaml and replace it’s <Grid> with the following:

    <StackPanel Margin="30,30,0,0">
        <TextBlock Text="Page 3" />
        <TextBlock x:Name="pagesTextBlock"
                   Text="" />
        <Button Content="Go Back"
                Click="Button_Click" />
    </StackPanel>

In the Page3.xaml.cs I’ll implement the following 

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            string myPages = "";
            foreach (PageStackEntry page in Frame.BackStack)
            {
                myPages += page.SourcePageType.ToString() + "\n";
            }

            pagesTextBlock.Text = myPages;

            Frame.BackStack.RemoveAt(Frame.BackStackDepth - 1);

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Frame.GoBack();
        }

Returning to Page2.xaml.cs, I’ll implement:

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Frame.Navigate(typeof(Page3));
        }

When I navigate from the MainPage to Page2 to Page3 by clicking buttons, I will see the following displayed on Page 3:

clip_image006

The key to this example is traversing the Frame.BackStack which is an IList<PageStackEntry>.  A PageStackEntry represents a page that was navigated to.

After I display the pages that we’ve travelled through to get to Page 3, I do the following:

Frame.BackStack.RemoveAt(Frame.BackStackDepth - 1);

This allows me to find the last page (Frame.BackStackDepth - 1) and remove it from the collection of pages.  The result?  When you click the “Go Back” button on Page 3, we navigate through the Frame.BackStack using the Frame.GoBack() method which will navigate to the last item in the Frame.BackStack … that should be the MainPage since we removed the Page2 BackStackEntry.

clip_image008

In addition to the Frame.GoBack(), there’s also a Frame.GoForward() which allows us to return to the previous page in the BackStack.

Recap

In this lesson we learned the absolute basics of navigation.  We learned about the purpose of the Frame object, and how to handle the OnNavigatedTo() method to retrieve values that are passed from one page to the next.  We learned how to create a NavigationContext class to allow us to pass more than one simple type between pages, and finally learned about the BackStack which is a collection of PageStackEntry objects, each object representing a page we’ve navigated through, and how to traverse the BackStack using the GoBack() and GoForward() methods.

Embed

Download

Download this episode

The Discussion

  • User profile image
    John Snow

    Bob,
    I've notice that all the pages you open default to the background including the space for the status back. Is there a settings in the options page that I missed in the intro that set that for you?

  • User profile image
    parosa

    Hi,

    It seems that there's a little misunderstanding here...

    I've been watching the videos from the series Building Apps for Windows Phone 8.1 Jump Start. On the third video of that series 03 - Page Navigation and Data Binding in Windows Runtime Apps, I learned that the behavior of the phone's hardware back button on Windows Phone Store apps differs from behavior on Windows Phone Silverlight apps.

    The behavior you talk about on the current video, e.g. the hardware back button navigates to the previous page on the app, is for Windows Phone Silverlight apps.

    The correct behavior for Windows Phone 8.1 Store apps, is that the phone's hardware back button allways navigates the user to the phone's start screen (the app is thus suspended), unless the app has the proper code to hook to the back button's event and change that behavior.

    Please have a look of on this video to see the difference from what you said on your video.

    http://channel9.msdn.com/Series/Building-Apps-for-Windows-Phone-8-1/03

    Cheers,

     

     

     

     

  • User profile image
    majid

    i try to navigate between home page and setting page and type frame.navigate(typeof(setting));
    but has error:
    system.windows.control.fram does not contain a definition for navigate

    please help me
    this is my first app

  • User profile image
    majid

    i try to navigate between home page and setting page and type frame.navigate(typeof(setting));
    but has error:
    system.windows.control.fram does not contain a definition for navigate

    please help me
    this is my first app

  • User profile image
    ThiagoBaltar

    Hi Bob.

    I literally just got started developing apps and I opted for Windows Phone 8.1.

     

    My question is how would I use the Back button of the phone to go back to the last page?

    Everytime I try, it returns to the emulator initial page.

     

    I tried using the HardwareButtons but unsuccessfully.

     

    Cheers.

  • User profile image
    bilalmustafa

    Bob, 

    how to use querystring in windows phone 8.1??

  • User profile image
    rajat tanwar

    how to close the app on hardware back button click in windows phone 8.1 app in visual studio 2013 proffessional

  • User profile image
    Marios Katsis

    @majid
    The frame.navigate(typeof(setting)); is not right
    You have to write
    Frame.Navigate(typeof(setting));

  • User profile image
    SAKHAWATSUM​IT

    It's little bit off topic,
    i was trying to navigate page in WPF.
    using 

    void startButton_Click(object sender, RoutedEventArgs e)
    {
    this.NavigationService.Navigate(new(Manu));
    }

    but it showing "MainWindow does not contain any definition of NavigationService".

    please help.

     

  • User profile image
    Somir Saikia

    Navigation between pages:-

    If Navigate from:-
    Page_1--> Page_2 --->Page_3 --> Page_1
    Using buttons and
    Frame.Navigate(typeof(Page_1));
    Always opens new pages where as it should reopen the previous Page_1.
    Is there any other method for Navigating between Pages?

Add Your 2 Cents