uwpprismprism-7

Prism 7 UWP Navigation Back Parameters Missing


Given A Prism 7 UWP Application with three Views and corresponding ViewModels:

containerRegistry.RegisterForNavigation<BlankPage1, BlankPage1ViewModel>();
containerRegistry.RegisterForNavigation<BlankPage2, BlankPage2ViewModel>();
containerRegistry.RegisterForNavigation<BlankPage3, BlankPage3ViewModel>();

If we navigate from BlankPage1 to BlankPage2 passing a parameter (from within a Command in ViewModel1):

public virtual DelegateCommand GoToPage2Command => new DelegateCommand(GoToPage2);
public virtual async void GoToPage2() {
     await NavigationService.NavigateAsync("BlankPage2", null, ("param", 5678));
}

In the OnNavigatedToAsync override of BlankPage2ViewModel the parameter is correctly passed in.

Now if we navigate from BlankPage2ViewModel to BlankPage3ViewModel, via a Command and pass another Parameter

public virtual DelegateCommand GoToPage3Command => new DelegateCommand(GoToPage3);
public virtual async void GoToPage3() {
    await NavigationService.NavigateAsync("BlankPage3", null, ("param", 1234));
}

Again this works and the parameter value 1234 is passed to BlankPage3ViewModel.

Now however if we navigate back to BlankPage2ViewModel:

await NavigationService.GoBackAsync();

No parameters are passed back into the OnNavigatedToAsync override of BlankPage2ViewModel. Surely we would expect to see the parameter value 5678?

NOTE: We also set NavigationCacheMode to Required inside each view.

An answer to a question asked over on the MSDN forums, regarding a similar issue states:

If you use Frame.Navigate to navigate to the same page, your PageA won't be reinstanciated but the OnNavigatedTo method will be called with the new parameters.

That way, you can change the information displayed on the page (even play some transition if needed); and as an added bonus the Frame history does keep your previous PageA parameters, allowing you to call Frame.GoBack to return to the previous PageA state.

Is this by design in Prism that no parameters are passed back or a potential bug?


Solution

  • As @Bite said, there's no problem in the general UWP project. When you call Frame.Navigate(typeof(page), "params"); method to navigate between the different pages and call Frame.GoBack() method to go back to the previous page, the parameters will be still there.

    Since you're using the Prism's navigation service, there should be some different places in it. If you want to know the detailed reason, you need to debug its Prism source code to know about the principle of its navigation service.

    Here, I'm also interested in its navigation service, so I spent some time to study on its source code. The core of navigation services should be in the NavigationService.cs and FrameFacade.cs.

    You could see that it finally will call the _frame.Navigate() method to navigate from one page to another page.

    var parameter = pageNavInfo.QueryString;
    return _frame.Navigate(
                      sourcePageType: pageNavInfo.View,
                      parameter: parameter,
                      infoOverride: infoOverride);
    

    The _frame object actually is a general UWP built-in Frame Class type. So, in general, the navigation parameters should be there when you call _frame.GoBack() to go back to the previous page.

    But, if you add some breakpoints to debug it, you would see that the parameter's value always is null in the above _frame.Navigate(sourcePageType: pageNavInfo.View,parameter:parameter,infoOverride: infoOverride); code block. That's the reason why you always cannot get the navigation parameter when call GoBack() method. It's because it always passes the null as parameter to the _frame.Navigate method. It has implemented its own NavigationParameters. All parameters that you passed to _navigationService.NavigateAsync() method should be in the '_external' parameters.

    enter image description here

    So, I've already told you the reason. I can't say it's by design or a potential issue. Maybe, they don't take into account the historical navigation parameters when calling 'GoBack()' method.You could submit your question to Github issue to see if there're workarounds from the official. Or if you are interested in it, you could try to change its source code and compile your own custom version for you.