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" );
}
}