Click here to Skip to main content
15,867,979 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a Xamarin.Forms application that has a requirement that I would have thought straightforward for the new Shell but is causing no end of problems.

I have some 'top-level' pages that can be freely navigated between using a TabBar.

One of these top-level pages, has a chain of children that are not part of the TabBar. This chain is terminated by one or more screens that are required to be modal. From these modal screens, I need to be able to jump right back to the 'home' screen.

The linked image shows this more clearly.

And most important is that I get navigation and page lifecycle events during each transition. (One reason I switched from the old push/pop navigation is because it does not give any event in the parent page when a child modal page closes on iOS.)

Can anyone give me some pointers how I might set this up using Xamarin.Forms.Shell?


https://www.dropbox.com/s/puq87x0f2l4lyn2/Navigation%20Requirements.png?dl=0[^]

What I have tried:

The following code almost works but when I jump back to the home screen from a modal screen, the Shell loses its styling. And note that the hamburger appears, even though the top-level navigation is a TabBar.

public partial class MyNavigation : Shell
{
	public MyNavigation()
	{
		Items.Add( new TabBar()
		{
			Items =
			{
				new ShellContent
				{
					ContentTemplate = new DataTemplate( typeof( HomeView ) ),
					Icon = ImageSource.FromResource( "Resources.Home.png" ),
					Route = "Home"
					},
				new ShellContent
				{
					ContentTemplate = new DataTemplate( typeof( SettingsView ) ),
					Icon = ImageSource.FromResource( "Resources.Settings.png" ),
					Route = "Settings" }
			}
		});
		Routing.RegisterRoute( "ChildScreenOne", typeof( ChildScreenOne ) );
		Routing.RegisterRoute( "ChildScreenTwo", typeof( ChildScreenTwo ) );
		Style = ControlStyles.Shell_BaseStyle;
	}
}

public class HomeView : ContentPage
{
	public HomeView()
	{
		Style = ControlStyles.ContentPage_BaseStyle;
		Title = "Home";
		Button _button = new Button { Text = "Goto Screen One" };
		Grid grid = new Grid()
		{
			RowDefinitions =
			{
				new RowDefinition { Height = GridLength.Star },
				new RowDefinition { Height = GridLength.Auto },
				new RowDefinition { Height = GridLength.Star }
			},
			ColumnDefinitions =
			{
				new ColumnDefinition { Width = GridLength.Star },
				new ColumnDefinition { Width = GridLength.Auto },
				new ColumnDefinition { Width = GridLength.Star }
			}
		};
		grid.Children.Add( _button, 1, 1 );
		_button.Clicked += _button_Clicked;
		Content = grid;
	}

	private async void _button_Clicked( Object sender, EventArgs e )
	{
		await Shell.Current.GoToAsync( "ChildScreenOne" );
	}
}

public class ChildScreenOne : ContentPage
{
	public ChildScreenOne()
	{
		Title = "Child Screen One";
		Style = ControlStyles.ContentPage_BaseStyle;
		Button _button = new Button { Text = "Goto Screen Two" };
		Grid grid = new Grid()
		{
			RowDefinitions =
			{
				new RowDefinition { Height = GridLength.Star },
				new RowDefinition { Height = GridLength.Auto },
				new RowDefinition { Height = GridLength.Star }
			},
			ColumnDefinitions =
			{
				new ColumnDefinition { Width = GridLength.Star },
				new ColumnDefinition { Width = GridLength.Auto },
				new ColumnDefinition { Width = GridLength.Star }
			}
		};
		grid.Children.Add( _button, 1, 1 );
		_button.Clicked += _button_Clicked;
		Content = grid;
	}

	private async void _button_Clicked( Object sender, EventArgs e )
	{
		await Shell.Current.GoToAsync( "ChildScreenTwo" );
	}
}

public class ChildScreenTwo : ContentPage
{
	public ChildScreenTwo()
	{
		Title = "Child Screen Two";
		Style = ControlStyles.ContentPage_BaseStyle;
		Button _button = new Button { Text = "Goto Home" };
		Grid grid = new Grid()
		{
			RowDefinitions =
			{
				new RowDefinition { Height = GridLength.Star },
				new RowDefinition { Height = GridLength.Auto },
				new RowDefinition { Height = GridLength.Star }
			},
			ColumnDefinitions =
			{
				new ColumnDefinition { Width = GridLength.Star },
				new ColumnDefinition { Width = GridLength.Auto },
				new ColumnDefinition { Width = GridLength.Star }
			}
		};
		grid.Children.Add( _button, 1, 1 );
		_button.Clicked += _button_Clicked;
		Content = grid;
		Shell.SetPresentationMode( this, PresentationMode.ModalAnimated );
	}

	private async void _button_Clicked( Object sender, EventArgs e )
	{
		await Shell.Current.GoToAsync( @"\\Home" );
	}
}
Posted
Updated 26-Apr-23 17:07pm
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900