Bug 56593 - Pushing multiple pages onto NavigationPage adds pages in reverse order
Summary: Pushing multiple pages onto NavigationPage adds pages in reverse order
Status: RESOLVED FIXED
Alias: None
Product: Forms
Classification: Xamarin
Component: Forms ()
Version: 2.3.4
Hardware: PC Windows
: Highest normal
Target Milestone: ---
Assignee: Rui Marinho
URL:
Depends on:
Blocks:
 
Reported: 2017-05-18 04:29 UTC by Brian Lagunas
Modified: 2017-06-28 00:40 UTC (History)
5 users (show)

Tags: navigation navigationstack pushasync ac
Is this bug a regression?: ---
Last known good build:


Attachments
repro project (295.55 KB, application/x-zip-compressed)
2017-05-19 19:07 UTC, Jimmy [MSFT]
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description Brian Lagunas 2017-05-18 04:29:34 UTC
When trying to build up a navigation stack and pushing from a Page that has a NavigationPage parent, the pages are added in the incorrect order, and the middle page is broken.

Given the following example, the expectation is that the final navigation stack would be: ViewA/ViewB/ViewC

Unfortunately the result is ViewA/ViewC/ViewB. Notice that page that should be last is in the middle.  Not only that, but ViewC is completely broken and no bindings are retained.  Not to mention all the Titles are messed up and are showing the wrong values.

	public partial class App : Application
	{
		public App()
		{			
			MainPage = new NavigationPage(new ViewA());
		}
	}

	public class ViewA : ContentPage
	{
		public ViewA()
		{
			Title = "View A";
			Button btn = new Button() { Text = "Navigate from ViewA", HorizontalOptions = LayoutOptions.Center, VerticalOptions = LayoutOptions.Center };
			btn.Clicked += Btn_Clicked;
			Content = btn;

		}

		private async void Btn_Clicked(object sender, System.EventArgs e)
		{
			var viewB = new ViewB();
			var viewC = new ViewC();

			await viewB.Navigation.PushAsync(viewC);

			await Navigation.PushAsync(viewB);
		}
	}

	public class ViewB : ContentPage
	{
		public ViewB()
		{
			Title = "View B";
			Content = new Label() { Text = "View B" };
		}
	}

	public class ViewC : ContentPage
	{
		public ViewC()
		{
			Title = "ViewC";
			Content = new Label() { Text = "ViewC" };
		}
	}
Comment 1 Jimmy [MSFT] 2017-05-19 19:07:55 UTC
Created attachment 22317 [details]
repro project

Thank you for filing this report! I am able to reproduce the issue you described using the project I am attaching.

However I believe the reason for this issue is that PushAsync() may not be the best way to modify the NavigationStack in order to achieve what you want. While PushAsync() does add the page to top of the NavigationStack, it will also immediately display that page. This is why when you press the Button you can briefly see ViewC displayed before ViewB is pushed which results in the incorrect order.

Fortunately there are ways to modify the stack that don't result in actual navigation. In this case, you can use InsertPageBefore() _after_ navigating to ViewC (or the page you want to be the last)  in order to add the pages to the stack in the correct order.

I also demonstrated this in the repro project so you can check it out. Using this approach also seems to resolve the issues you mention in bug 44115 and bug 45978.
Comment 2 Brian Lagunas 2017-05-21 16:34:03 UTC
Unfortunately, your work around does not apply to the actual situation.  The repro I provided was meant to only reproduce the behavior, not to represent the actual scenario in an app.

This behavior is a blocking issue to the deep linking navigation feature in the Prism framework.  Prism accepts any navigation link with multiple pages to build up the navigation stack.

Example "MasterDetailPage/NavigationPage/ViewA/ViewB/ViewC/TabbedPage".  This navigation link would generate the pages and add them tot the stack in the expected order.

Given this, I do not know the intent of the navigation and cannot use "InsertPageBefore".

If may be helpful if you added someone to this thread that is more familiar with Prism and it's navigation feature such as Jason Smith.
Comment 3 Jimmy [MSFT] 2017-05-22 21:16:06 UTC
Apologies for the confusion! Given that information, I will confirm the report so this can be investigated further. Thanks!
Comment 4 Brian Lagunas 2017-05-22 23:35:34 UTC
If it helps I can attached a Prism application that demonstrates the issue. Let me know.
Comment 5 Rui Marinho 2017-06-14 12:19:50 UTC
https://github.com/PrismLibrary/Prism/pull/1082
Comment 6 Brian Lagunas 2017-06-28 00:40:43 UTC
This has been fixed with Rui's awesome PR.