Summary of Chapter 24. Page navigation
Many applications consist of multiple pages among which the user navigates. The application always has a main page or home page, and from there the user navigates to other pages, which are maintained in a stack for navigating back. Additional navigation options are covered in Chapter 25. Page Varieties.
Modal pages and modeless pages
Both methods accept a
Page instance as an argument and return a
Task object. The following two methods navigate back to the previous page:
If the user interface has its own Back button (as Android and Windows phones do) then it's not necessary for the application to call these methods.
Although these methods are available from any
VisualElement, generally they are called from the
Navigation property of the current
Applications generally use modal pages when the user is required to supply some information on the page before returning to the previous page. Pages that are not modal are sometimes called modeless or hierarchical. Nothing in the page itself distinguishes it as modal or modeless; it's governed instead by the method used to navigate to it. To work across all platforms, a modal page must provide its own user interface for navigating back to the previous page.
The ModelessAndModal sample allows you to explore the difference between modeless and modal pages. Any application that uses page navigation must pass its home page to the
NavigationPage constructor, generally in the program's
App class. One bonus is that you no longer need to set a
Padding on the page for iOS.
You will discover that for modeless pages, the page's
Title property is displayed. The iOS, Android, and the Windows tablet and desktop platforms all provide a user-interface element to navigate back to the previous page. Of course, Android, and Windows phone devices have a standard Back button to go back.
For modal pages, the page
Title is not displayed, and no user-interface element is provided to go back to the previous page. Although you can use the Android and Windows phone standard Back button to return to the previous page, the modal page on the other platforms must provide its own mechanism to go back.
Animated page transitions
Alternative versions of the various navigation methods are provided with a second Boolean argument that you set to
true if you want the page transition to include an animation:
However, the standard page-navigation methods include the animation by default, so these are only valuable for navigating to a particular page on startup (as discussed towards the end of this chapter) or when providing your own entrance animation (as discussed in Chapter22. Animation).
Visual and functional variations
NavigationPage includes two properties that you can set when you instantiate the class in your
NavigationPage also includes four attached bindable properties that affect the particular page on which they are set:
GetBackButtonTitlework on iOS only
GetTitleIconwork on iOS and Android only
Exploring the mechanics
The page navigation methods are all asynchronous and should be used with
await. The completion doesn't indicate that page navigation has completed, but only that it's safe to examine the page-navigation stack.
When one page navigates to another, the first page generally gets a call to its
OnDisappearing method, and the second page gets a call to its
OnAppearing method. Similarly, when one page returns to another, the first page gets a call to its
OnDisappearing method, and the second page generally gets a call to its
OnAppearing method. The order of these calls (and the completion of the asynchronous methods that invokes the navigation) is platform dependent. The use of the word "generally" in the two preceding statements is due to Android modal-page navigation, in which these method calls don't occur.
Also, calls to the
OnDisappearing methods don't necessarily indicate page navigation.
INavigation interface includes two collection properties that allow you to examine the navigation stack:
IReadOnlyList<Page>for the modeless stack
IReadOnlyList<Page>for the modal stack
It is safest to access these stacks from the
Navigation property of the
NavigationPage (which should be the
MainPage property). It is only safe to examine these stacks after the asynchronous page-navigation methods have completed. The
CurrentPage property of the
NavigationPage does not indicate the current page if the current page is a modal page, but indicates instead the last modeless page.
The SinglePageNavigation sample lets you explore page navigation and the stacks, and the legal types of page navigations:
- A modeless page can navigate to another modeless page or a modal page
- A modal page can navigate only to another modal page
An application uses a modal page when it's necessary to obtain some information from the user. The user should be prohibited from returning to the previous page until that information is provided. On iOS, it's easy to provide a Back button and enable it only when the user has finished with the page. But for Android and Windows phone devices, the application should override the
OnBackButtonPressed method and return
true if program has handled the Back button itself, as demonstrated in the ModalEnforcement sample.
The MvvmEnforcement sample demonstrates how this works in an MVVM scenario.
If a particular modal page can be navigated to multiple times, it should retain information so that the user can edit the information rather than typing it all in again. You can handle this by retaining the particular instance of the modal page, but a better approach (particularly on iOS) is preserving the information in a view model.
Making a navigation menu
The ViewGalleryType sample demonstrates using a
TableView to list menu items. Each item is associated with a
Type object for a particular page. When that item is selected, the program instantiates the page and navigates to it.
The ViewGalleryInst sample is a little different in that the menu contains instances of each page rather than types. This helps retain the information from each page, but all the pages must be instantiated at program startup.
Manipulating the navigation stack
StackManipulation demonstrates several functions defined by
INavigation that let you manipulate the navigation stack in a structured manner:
Dynamic page generation
The BuildAPage sample demonstrates constructing a page at runtime based on user input.
Patterns of data transfer
It is often necessary to share data between pages — to transfer data to a navigated page, and for a page to return data to the page that invoked it. There are several techniques for doing this.
When navigating to a new page, it's possible to instantiate the page class with a constructor argument that allows the page to initialize itself. The
SchoolAndStudents sample demonstrates this. It's also possible for the navigated page to have its
BindingContext set by the page that navigates to it.
Properties and method calls
The remaining data transfer examples explore the problem of passing information between pages when one page navigates to another page and back. In these discussions, the home page navigates to the info page, and must transfer initialized information to the info page. The info page obtains additional information from the user and transfers the information to the home page.
The home page can easily access public methods and properties in the info page as soon as it instantiates that page. The info page can also access public methods and properties in the home page, but choosing a good time for this can be tricky. The DateTransfer1 sample does this in its
OnDisappearing override. One drawback is that the info page needs to know the type of the home page.
MessagingCenter class provides another way for two pages to communicate with each other. Messages are identified by a text string and can be accompanied by any object.
A program that wishes to receive messages from a particular type must subscribe to them using
MessagingCenter.Subscribe and specify a callback function. Later it can unsubscribe by calling
MessagingCenter.Unsubscribe. The callback function receives any message sent from the specified type with the specified name sent through the
The DateTransfer2 program demonstrates how to transfer data using the messaging center, but again this requires that the info page know the type of the home page.
The event is a time-honored approach for one class to send information to another class without knowing that class's type. In the DateTransfer3 sample the info class defines an event that it fires when the information is ready. However, there is no convenient place for the home page to detach the event handler.
The App class intermediary
The DateTransfer4 sample shows how to access properties defined in the
App class by both the home page and the info page. This is a good solution, but the next section describes something better.
Switching to a ViewModel
Using a ViewModel for the information allows the home page and the info page to share the instance of the information class. This is demonstrated in the DateTransfer5 sample.
Saving and restoring page state
App class intermediary or the ViewModel approach is ideal when the application must save information if the program goes to sleep while the info page is active. The
DateTransfer6 sample demonstrates this.
Saving and restoring the navigation stack
In the general case, a multipage program that goes to sleep should navigate to the same page when it is restored. This means that such a program should save the contents of the navigation stack. This section shows how to automate this process in a class designed for this purpose. This class also calls the individual pages to allow them to save and restore their page state.
MultiPageRestorableApp class in the Xamarin.FormsBook.Toolkit library derives from
Application. You can then derive your
App class from
MultiPageRestorableApp and perform some housekeeping.
The StackRestoreDemo demonstrates the use of
Something like a real-life app
The NoteTaker sample also makes use of
MultiPageRestorableApp and allows for the entering and editing of notes that are saved in the