ShellIntro-870x220

The new Xamarin.Forms Shell is meant to boost mobile developer productivity. App content organization and navigation is nicely abstracted away by the Shell, thus allowing developers more time to focus on app content. This article explores the basics of Xamarin.Forms Shell and how to get started.

Mobile app development should be fun. But the realities of enterprise app development often put mobile developers under tight timelines. Indie developers authoring mobile apps are often trying to squeeze the most out of nights and weekends. Any framework, tool or technique that gives mobile developers productivity boosts is thus very welcome.

Now, most foodies will agree - a good burrito 🌯 is pure bliss. You get to pick a wrapper that suits your taste and what goes inside is whatever your heart desires. And yes, all burritos should be customizable. But, what does a food reference got anything to do with mobile development?

Mobile developers are often looking for shortcuts - a good starting point definitely is worth it. Wouldn't it be nice if we could get some boilerplate functionality out of the box and be able to focus on app functionality? Most apps follow some structure with content organization and navigation - wouldn't it be nice to get something beautiful out of the box that works cross-platform seamlessly? What app developers want is a burrito shell - and then be able to fill it up with app content.

Xamarin.Forms makes it incredibly easy for .NET developers to build apps for iOS, Android & much more. Xamarin.Forms allows for building truly native apps from a single shared code base - apps with beautiful native UI.

Xamarin.Forms 4.0 shipped earlier this year and it seriously upped the UI game with the introduction of the Shell. Much like how Xamarin.Forms abstracts away user interface elements into an easy to use API, Shell abstracts away app architecture and navigation complexity.

Shell provides a container for your app. That container includes a MasterDetailPage, a TabbedPage, and a NavigationPage or a combination thereof. Shell also provides a rudimentary search functionality. And, to top it off, it has URI based navigation baked right in. It's almost like the Shell is the tortilla of our app burrito and the pages are the delicious fillings! Now that we have driven the burrito metaphor to the ground, let's dive in and create a Shell-based Xamarin.Forms app!

Our Demo App

First off, here's the app we'll create today.

ShellDemo
 

It's like a tourist guide to Seattle - except just a demo app. It has a MasterDetailPage with 2 children - one of which is a TabbedPage, the other is a regular old ContentPage. That TabbedPage has 2 tabs. Each page in those tabs has a ListView and tapping on the ListView items will navigate around the app. You can grab all of the demo code for this app on GitHub, clone it and follow along! Cool? Cool.

Shell Basics

To make an app into a Shell app, you need a Shell page. And that looks like this:

<?xml version="1.0" encoding="UTF-8"?>  
    <Shell
        xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:pages="clr-namespace:ShellDemo"  
        x:Class="ShellDemo.ShellPage">
    </Shell>

Then in your Application page's constructor:

public App()
{
    InitializeComponent();
    MainPage = new ShellPage();
}

Documentation for Xamarin.Forms Shell has a ton of in-depth info on bootstrapping a Shell application. Now let's make that shell contain something!

Shell Components

As mentioned, there are 3 main components of a Shell application - the MasterDetailPage (or flyout), the TabbedPage, and the NavigationPage. You can use these all together, or pick and choose as you see fit. Let's start with the MasterDetailPage.

The Flyout

Looking at the app above, there are two 'detail' pages for the MasterDetailPage. One is a TabbedPage and the other is a ContentPage. So let's look at how you would add that ContentPage:

<Shell>
    <FlyoutItem Title="Tourist Site of the Day">
        <pages:TouristSitePage Title="Tourist Site" />
    </FlyoutItem>
</Shell>

That's pretty straightforward. Within the <Shell> element, we put in a <FlyoutItem> element. And within that, a reference to your custom page.

Now let's take a minute to stop and look at some shortcuts when building up the Shell. There are other elements such as <ShellContent> that could go into this hierarchy. But the Xamarin.Forms team has made it so the XAML parser will put those in for you if you omit them. Xamarin.Forms already knows that <pages:TouristSitePage> should be within a <ShellContent>. So we can omit that and let Forms do the work. You can dive deep in the Flyout mechanics in the Docs or read up more on what else Forms does for you.

The Tabs

The next step is to add the TabbedPage. Or Tabs as Shell likes to call them. Since that's also a part of the MasterDetailPage, it will go into a FlyoutItem as well. And then to tell Xamarin.Forms to render that particular FlyoutItem as tabs, you put <Tab> elements in it.

The syntax looks like this:


<FlyoutItem Title="City Info">
    <Tab Title="City Info">
        <pages:CityInfoPage Title="City Info" />
    </Tab>
    <Tab>
        <pages:BusRoutePage Title="Bus Routes" />
    </Tab>
</FlyoutItem>

Now we're getting somewhere. A MasterDetailPage wrapping up a TabbedPage with two tabs and a regular ContentPage.

What if you don't want a MasterDetailPage at all? Leave out the FlyoutItem elements. Only put in <Tab> elements. And if you wanted, you could wrap all those <Tab> elements in a <TabBar> element too. And here's the best thing, by default, all the bottom-most pages are already inside a NavigationPage.

You know what that means, it's time to do some navigation!

Navigation

Shell gives us something called URI-based routing. That means you give a page a string identifier, then call Shell.Current.GoToAsync passing in that page's identifier. And .. you pass along arguments to the new page as query string parameters.

So in the case of the bus stop page: since it's not referenced anywhere in the <Shell> page's XAML, we need to define a route for it. We do that in the constructor of our Shell page:

public ShellPage()
{
    InitializeComponent();
    Routing.RegisterRoute("busstop", typeof(BusStopPage));
}

This is going to allow Shell to navigate to the BusStopPage. And we'll do that in the BusRoutePage's ListView.ItemSelected event:

async void Handle_ItemSelected(object sender, SelectedItemChangedEventArgs args)
{
    var selectedRoute = e.SelectedItem as BusRouteInfo;

    await Shell.Current.GoToAsync($"busstop=route{selectedRoute.RouteNumber}");
}

Shell then will new up the BusStopPage and navigate to it, passing in the bus route number of the selected item. How do you get at that passed in parameter? There's a class level attribute you can use. It specifies what the incoming parameter's name will be along with a property in the class it should populate.

So here's what that looks like:

[QueryProperty("RouteNumber", "route")]  
public partial class BusStopPage : ContentPage

The route parameter will populate the RouteNumber property. There's a lot more to navigation within the Shell. Docs are here to help.

Summing Up

There you have it - Xamarin.Forms Shell abstracting away some of the complexities of building apps into an intuitive API. The <Shell> element is the basis of it all. To that you add <FlyoutItem> to create a MasterDetailPage. Within those items, you add either <Tab> elements to create a TabbedPage or your custom pages. Within the <Tab> elements add your custom pages. And you can navigate all around using Shell's brand new URI-based navigation.

There's a whole lot more that Shell can do, including searching and a host of visual styling. As always, Docs are the best place to start - more Shell deep dive articles coming up here. And did you know that Telerik UI for Xamarin works seamlessly with the new Xamarin.Forms Shell? Good times indeed. Enjoy your burrito!


Matt Soucoup
About the Author

Matt Soucoup

Matthew Soucoup is a Senior Cloud Developer Advocate at Microsoft spreading the love of integrating Azure with Xamarin. Matt is also a Pluralsight author, a Telerik Developer Expert and prior to joining Microsoft a founder of a successful consulting firm targeting .NET and web development. Follow Matt on Twitter at @codemillmatt and his personal blog at codemillmatt.com.

Comments

Comments are disabled in preview mode.