Universal Apps: Navigation

  1. Overview
    1. Apps may consist of multiple pages (multi-page navigation) or use a single-page navigation model
    2. For example, the main page lists all the available articles, a second page shows the article details, and a third page show subscription info
    3. Each page is equivalent to a new window
    4. See Navigation for UWP apps
  2. The Frame class maintains an internal stack of visited pages
    1. App class (App.xaml.cs) creates and sets the window's Frame in OnLaunched()
      protected async override void OnLaunched(LaunchActivatedEventArgs e)
      {
      ...	
      	Frame rootFrame = Window.Current.Content as Frame;
      	
      	// Do not repeat app initialization when the Window already has content,
      	// just ensure that the window is active
      	if (rootFrame == null)
      	{
      		// Create a Frame to act as the navigation context and navigate to the first page
      		rootFrame = new Frame();	
      ...	
      		// Place the frame in the current Window
      		Window.Current.Content = rootFrame;
      	}
      
    2. Starting page (MainPage) is navigated to in OnLaunched()
      rootFrame.Navigate(typeof(MainPage), e.Arguments);
      
  3. Navigating to a page
    1. Add a Blank Page to your app project called SecondPage
    2. Use Frame.Navigate() to navigate to the new page
      this.Frame.Navigate(typeof(SecondPage));
      
    3. Pages are notified when they are navigated to/from using OnNavigatedTo and OnNavigatedFrom methods
      protected override void OnNavigatedTo(NavigationEventArgs args)
      {
      	// Page was navigated to
      }
      
      protected override void OnNavigatedFrom(NavigationEventArgs args)
      {
      	// Page is being navigated away from
      }
      
    4. Can send any object to the new page
      1. Example sending a string
        this.Frame.Navigate(typeof(SecondPage), "Message for SecondPage");
        
      2. SecondPage can retrieve the object in OnNavigatedTo
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        	string message = e.Parameter as string;
            if (string.IsNullOrWhiteSpace(message))
                myTextBox.Text = "Go back and give me a message!";
            else
        		myTextBox.Text = "Received " + message;        
        }
        
    5. Going back and forward
      1. Use GoBack and GoForward methods to navigate through the stack
        this.Frame.GoBack();      // Go to previous page
        this.Frame.GoForward();   // Go to next page
        
      2. Back button displays in a desktop app's title bar, but you must add code to make it display
      3. In App.xaml.cs in OnLaunched, add 1) Navigated handler, 2) BackRequested handler. Add both handlers as well.
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {
        	...
        	if (rootFrame == null)
        	{
        		rootFrame = new Frame();
        		
        		// ADD: Register Navigated event handler
        		rootFrame.Navigated += OnNavigated;
        		...
        		
        		// ADD: Register BackRequested event handler 
        		SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
        	}
        	...
        }
        
        // ADD: Navigated event handler
        private void OnNavigated(object sender, NavigationEventArgs e)
        {
        	// Determine if Back button should be visible
        	SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
        		((Frame)sender).CanGoBack ?
        		AppViewBackButtonVisibility.Visible :
        		AppViewBackButtonVisibility.Collapsed;
        }
        
        // ADD: BackRequested event handler
        private void OnBackRequested(object sender, BackRequestedEventArgs e)
        {
        	Frame rootFrame = Window.Current.Content as Frame;
        	if (rootFrame.CanGoBack)
        	{
        		e.Handled = true;
        		rootFrame.GoBack();
        	}
        }
        
    6. When navigating back to page, the page is instantiated again and reset to default view
      1. Any data entered into text boxes will be lost
      2. Turn on caching to keep a single instance of each page in cache which is reused every time the page is visited
        public MainPage()
        {
        	this.InitializeComponent();
        	this.NavigationCacheMode = NavigationCacheMode.Enabled;
        }