PROWAREtech

articles » archived » xamarin » tutorial » page-09

Xamarin: Tutorial - Page 09

A guide for new Xamarin developers.

Page Navigation

Pages are either modal or modeless. Modal means user interaction is required before continuing. Simply put, modeless is a page that is not modal.

Page navigation appears to use a stack data structure to keep a list of open pages. Use Navigation.PushModalAsync() to open a modal page and Navigation.PushAsync() to open a modeless one. Use Navigation.PopModalAsync() and Navigation.PopAsync() to destroy the current page and goes back to the previous one.

Example Code

The following code demonstrates the difference between modal and modeless.

<?xml version="1.0" encoding="utf-8"?>
<!--MainPageXaml.xaml-->
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
		xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
		xmlns:local="clr-namespace:HelloXamarinForms"
		x:Class="HelloXamarinForms.MainPageXaml"
		Title="Main Page">

	<ContentPage.Padding>
		<OnPlatform x:TypeArguments="Thickness" iOS="20" Android="20, 0, 20, 20" />
	</ContentPage.Padding>

	<StackLayout>
		<Button Text="Open Modal Page" Clicked="ModalPageClicked" />
		<Button Text="Open Modeless Page" Clicked="ModelessPageClicked" />
	</StackLayout>
	
</ContentPage>
// MainPageXaml.xaml.cs
using Xamarin.Forms;

namespace HelloXamarinForms
{
	public partial class MainPageXaml : ContentPage
	{
		public MainPageXaml()
		{
			InitializeComponent();
		}

		async void ModalPageClicked(object sender, System.EventArgs e)
		{
			await Navigation.PushModalAsync(new ModalPage());
		}

		async void ModelessPageClicked(object sender, System.EventArgs e)
		{
			await Navigation.PushAsync(new ModelessPage());
		}
	}
}
<?xml version="1.0" encoding="utf-8" ?>
<!--ModelessPage.xaml-->
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
			 xmlns:local="clr-namespace:HelloXamarinForms"
			 x:Class="HelloXamarinForms.ModelessPage"
			 Title="Modeless Page">

	<ContentPage.Padding>
		<OnPlatform x:TypeArguments="Thickness" iOS="20" Android="20, 0, 20, 20" />
	</ContentPage.Padding>

	<StackLayout>
		<Label Text="Modeless Page Label"
					VerticalOptions="Center"
					HorizontalOptions="Center" />
		<Button Text="Back" Clicked="BackClicked" />
	</StackLayout>
</ContentPage>
// ModelessPage.xaml.cs
using Xamarin.Forms;

namespace HelloXamarinForms
{
	public partial class ModelessPage : ContentPage
	{
		public ModelessPage()
		{
			InitializeComponent();
		}

		async void BackClicked(object sender, System.EventArgs e)
		{
			await Navigation.PopAsync();
		}
	}
}
<?xml version="1.0" encoding="utf-8" ?>
<!--ModalPage.xaml-->
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
			 xmlns:local="clr-namespace:HelloXamarinForms"
			 x:Class="HelloXamarinForms.ModalPage"
			 Title="Modal Page">

	<ContentPage.Padding>
		<OnPlatform x:TypeArguments="Thickness" iOS="20" Android="20, 0, 20, 20" />
	</ContentPage.Padding>

	<StackLayout>
		<Label Text="Modal Page Label"
					VerticalOptions="Center"
					HorizontalOptions="Center" />
		<Button Text="Close" Clicked="BackClicked" />
	</StackLayout>
</ContentPage>
// ModalPage.xaml.cs
using Xamarin.Forms;

namespace HelloXamarinForms
{
	public partial class ModalPage : ContentPage
	{
		public ModalPage()
		{
			InitializeComponent();
		}

		async void BackClicked(object sender, System.EventArgs e)
		{
			await Navigation.PopModalAsync();
		}
	}
}
// App.xaml.cs
using Xamarin.Forms;

namespace HelloXamarinForms
{
	public partial class App : Application
	{
		public App()
		{
			InitializeComponent();

			MainPage = new NavigationPage(new MainPageXaml());
		}

		protected override void OnStart()
		{
			// Handle when your app starts
		}

		protected override void OnSleep()
		{
			// Handle when your app sleeps
		}

		protected override void OnResume()
		{
			// Handle when your app resumes
		}
	}
}

Screen Shots

These images are of the above code running on Android. The behavior is pretty much identical on iOS with the only difference being that Android has a back button on the device so the user can go back even on modal forms. iOS cannot go back on modal forms unless a back or close button is placed on the form by the programmer.

Some things to remember about modal and modeless pages are:

  • You can open a modal page over any page (modeless or modal).
  • You cannot open a modeless page over a modal one.
  • Modeless pages only work with a NavigationPage.

Changing the Navigation Bar

BarBackgroundColor and BarTextColor modify the navigation bar at the top of the screen.

// App.xaml.cs
using Xamarin.Forms;

namespace HelloXamarinForms
{
	public partial class App : Application
	{
		public App()
		{
			InitializeComponent();

			MainPage = new NavigationPage(new MainPageXaml())
			{
				BarBackgroundColor = Color.Navy,
				BarTextColor = Color.White
			};
		}

		protected override void OnStart()
		{
			// Handle when your app starts
		}

		protected override void OnSleep()
		{
			// Handle when your app sleeps
		}

		protected override void OnResume()
		{
			// Handle when your app resumes
		}
	}
}

Also, it is possible to remove the back button on the navigation bar of modeless pages. Here it is done in the XAML.

<?xml version="1.0" encoding="utf-8" ?>
<!--ModelessPage.xaml-->
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
			 xmlns:local="clr-namespace:HelloXamarinForms"
			 x:Class="HelloXamarinForms.ModelessPage"
			 Title="Modeless Page"
			 NavigationPage.HasBackButton="False">
			 <!--NavigationPage.HasBackButton="True" is the default-->

	<ContentPage.Padding>
		<OnPlatform x:TypeArguments="Thickness" iOS="20" Android="20, 0, 20, 20" />
	</ContentPage.Padding>

	<StackLayout>
		<Label Text="Modeless Page Label" VerticalOptions="Center" HorizontalOptions="Center" />
		<Button Text="Back" Clicked="BackClicked" />
	</StackLayout>
</ContentPage>

Here, it is done in the code-behind file of the XAML form.

// ModelessPage.xaml.cs
using Xamarin.Forms;

namespace HelloXamarinForms
{
	public partial class ModelessPage : ContentPage
	{
		public ModelessPage()
		{
			InitializeComponent();

			NavigationPage.SetHasBackButton(this, false);
		}

		async void BackClicked(object sender, System.EventArgs e)
		{
			await Navigation.PopAsync();
		}
	}
}

SetHasNavigationBar() is used to eliminate the navigation bar from the page.

// ModelessPage.xaml.cs
using Xamarin.Forms;

namespace HelloXamarinForms
{
	public partial class ModelessPage : ContentPage
	{
		public ModelessPage()
		{
			InitializeComponent();

			NavigationPage.SetHasNavigationBar(this, false);
		}

		async void BackClicked(object sender, System.EventArgs e)
		{
			await Navigation.PopAsync();
		}
	}
}
<<<[Page 9 of 11]>>>

PROWAREtech

Hello there! How can I help you today?
Ask any question
This site uses cookies. Cookies are simple text files stored on the user's computer. They are used for adding features and security to this site. Read the privacy policy.
CLOSE