This project is read-only.

Passing Parameters During Navigation

The Prism for Windows Runtime Microsoft.Practices.Prism.StoreApps library provides you with a navigation service that you can use to navigate between the different pages that form part of your application. This navigation service also allows you to pass a parameter during navigation, from the current page to the next one, allowing it to initialize itself according to that parameter.

What you can pass as a parameter during a navigation request is limited: the navigation service provided by Prism uses the standard Frame class to perform most of the navigation process. This includes managing the navigation history and the parameters passed in each navigation request plus serializing the navigation state in order to save and restore the state of the application when it’s suspended and resumed. Therefore, any parameter passed during navigation should be supported for serialization by the Frame class, so that it could be saved and loaded accordingly.

In this article there are some approaches that you might find useful to pass information between pages when navigating while keeping your navigation parameters serializable by the Frame class.

Passing a simple parameter type

The MSDN article for the GetNavigationState method of the Frame class mentions that:

“The serialization format used by these methods (GetNavigationState and SetNavigationState) is for internal use only. Your app should not form any dependencies on it. Additionally, this format supports serialization only for basic types like string, char, numeric and GUID types.”

Therefore, if the information you want to pass is contained a basic type, like a string or a number, then you should be able to pass it directly as a parameter when performing a navigation request without problems:

private void Navigate()
{
    this.navigationService.Navigate("Page", "string");
}
And consume that parameter in the OnNavigatedTo method of the page.

Passing an object identifier

Often when performing a navigation request you might be tempted to pass more information than what a basic type can hold, like a DTO or a Model object. In such cases you should check if it’s possible to obtain such object in the navigated-to view using another source besides the navigation parameter.

Think, for example, of a ProductsPage and a ProductDetailPage. The ProductsPage could show a list of products and upon selection of one of those products we want to navigate to the ProductDetailPage to show its details. However, we need to inform the ProductDetailPage which product it should show and we cannot pass the Product model directly as the navigation parameter.

When working in this kind of scenario, you would usually have a repository that acts as the data provider in your application. In this example, we should have a ProductRepository where we obtain the data for each Product. Therefore, in the ProductDetailPage we could obtain the corresponding Product from the repository and pass in the navigation parameter the minimum amount of information required to do so: for example, the product ID.

// In the ProductsPage
public void GoToDetails()
{
    this.navigationService.Navigate("ProductDetail", SelectedProduct.Id);
}

// In the ProductDetailPage
public override void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
{
    base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);
    
    int? id = navigationParameter as int?;
    if (id != null)
    {
        Product product = this.productRepository.GetProduct(id);
        ...
    }

}
As a basic rule the navigation parameter should always contain the minimum information possible. For example, you should never send the content that a page has to display in the parameter, but you can pass an id that you can use to obtain that content from other sources.

There are several reasons behind this. For example, anything passed as a parameter during navigation will be kept alive in the navigation history of the Frame and saved and loaded when the application is suspended and resumed, consuming memory. Also, any data passed in the navigation parameter that could be changed later will not be kept up to date.

Passing a Data Transfer Object (DTO) as the parameter

You might find some scenarios where the minimum amount of information you need to pass cannot be expressed directly as a primitive. In such cases, you would usually encapsulate the information you need to pass in a DTO. However, as mentioned above, you can only pass primitive types as the navigation parameter, meaning you cannot pass your DTO directly.

A possible approach to work around this is to serialize your DTO as a string before attempting to pass it in the navigation parameter. Then, in the navigated-to page you would deserialize the DTO object to consume it. Although this seems like a simple approach, you should take into account the following points if you choose to follow it:
  • The DTO should only contain the minimum amount of information possible. If you need to pass a large amount of data, you should save it in a service or a repository and obtain it from there.
  • The process of serializing and deserializing the object might reduce the performance of your application depending on the object.
  • Any information contained in the DTO should not be changeable during this time. If the information changes (for example, the stock available for a product) the information contained in the parameter will be outdated.

Last edited Jun 6, 2013 at 4:11 PM by DCherubini, version 2

Comments

No comments yet.