Reduce Xamarin.Forms Shell Template to Bare Minimum

PeterMilovcik - Jan 23 '20 - - Dev Community

If you want to start with Xamarin.Forms Shell application, there are two options.

  1. Start with Blank template, create Shell manually then adapt the rest of code.
  2. Start with Shell template and then remove unnecessary generated code which we might not need to use at all.

Let's take a look on the 2nd option:

XamarinFormsShellTemplate

The template already creates some additional files like:

In Models directory:

  • Item.cs

In Services directory:

  • IDataStore.cs
  • MockDataStore.cs

In ViewModels directory:

  • AboutViewModel.cs
  • BaseViewModel.cs
  • ItemDetailViewModel.cs
  • ItemsViewModel.cs

In Views directory:

  • AboutPage.xaml
  • AboutPage.xaml.cs
  • ItemDetailPage.xaml
  • ItemDetailPage.xaml.cs
  • ItemsPage.xaml
  • ItemsPage.xaml.cs
  • NewItemPage.xaml
  • NewItemPage.xaml.cs

Delete code

If you want to have a clean and empty Shell application start by deleting all these files except BaseViewModel.cs which contains some useful implementation of INotifyPropertyChanged interface so that you don't have to implement it by yourself again. Keep the directories, they help to keep code organized in well named namespaces.

If you try to build the solution after deleting those files you would get multiple compilation errors. That's expected, we are not done yet.

Open BaseViewModel.cs file and delete:

using XamarinNavigation.Models;
using XamarinNavigation.Services;
Enter fullscreen mode Exit fullscreen mode

and property

public IDataStore<Item> DataStore => DependencyService.Get<IDataStore<Item>>();
Enter fullscreen mode Exit fullscreen mode

Open App.xaml.cs file and delete:

using XamarinNavigation.Services;
using XamarinNavigation.Views;
Enter fullscreen mode Exit fullscreen mode

and registration on dependency service:

DependencyService.Register<MockDataStore>();
Enter fullscreen mode Exit fullscreen mode

If you try to build solution again, you still get compilation error that says something like:

Type ItemsPage not found in xmlns clr-namespace: ... AppShell.xaml
Enter fullscreen mode Exit fullscreen mode

This is also expected, since we deleted ItemsPage.xaml, so lets create new ContentPage called (e.g.) MainView.xaml and place it in Views directory, like this:

New MainView

NewMainView

MainView.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="XamarinNavigation.Views.MainView">
    <ContentPage.Content>
        <StackLayout>
            <Label Text="Welcome to Xamarin.Forms!"
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="CenterAndExpand" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>
Enter fullscreen mode Exit fullscreen mode

MainView.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace XamarinNavigation.Views
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MainView : ContentPage
    {
        public MainView()
        {
            InitializeComponent();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Adapt AppShell.xaml

Now, change the AppShell.xaml to have only single page (without any additional flyouts or tabs):

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="XamarinNavigation.AppShell"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:d="http://xamarin.com/schemas/2014/forms/design"
    xmlns:local="clr-namespace:XamarinNavigation.Views"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="XamarinNavigation"
    mc:Ignorable="d">

    <Shell.Resources>
        <ResourceDictionary>
            <Color x:Key="NavigationPrimary">#2196F3</Color>
            <Style x:Key="BaseStyle" TargetType="Element">
                <Setter Property="Shell.BackgroundColor" Value="{StaticResource NavigationPrimary}" />
                <Setter Property="Shell.ForegroundColor" Value="White" />
                <Setter Property="Shell.TitleColor" Value="White" />
                <Setter Property="Shell.DisabledColor" Value="#B4FFFFFF" />
                <Setter Property="Shell.UnselectedColor" Value="#95FFFFFF" />
                <Setter Property="Shell.TabBarBackgroundColor" Value="{StaticResource NavigationPrimary}" />
                <Setter Property="Shell.TabBarForegroundColor" Value="White" />
                <Setter Property="Shell.TabBarUnselectedColor" Value="#95FFFFFF" />
                <Setter Property="Shell.TabBarTitleColor" Value="White" />
            </Style>
            <Style BasedOn="{StaticResource BaseStyle}" TargetType="TabBar" />
        </ResourceDictionary>
    </Shell.Resources>

    <TabBar>
        <Tab Title="Main" Icon="xamarin_logo.png">
            <ShellContent ContentTemplate="{DataTemplate local:MainView}" />
        </Tab>
    </TabBar>

</Shell>
Enter fullscreen mode Exit fullscreen mode

Now, build and start your newly created Shell the application:

EmptyShellApp

Note: if you have an empty flyout (hamburger menu) still visible, it probably means that you are on Xamarin.Forms 4.2, which has this bug inside. Solution is to update your NuGet Xamarin.Forms package to latest stable version. If you plan to use flyout anyway, then you can stay with 4.2 if you want to.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .