Shell | Getting Started
Make .NET MAUI Shell shinier with viewmodel lifecycle management, navigation, and source generation to remove boilerplate, reduce errors, and make your app testable.
Inspired by Prism Library by Dan Siegel and Brian Lagunas.
Features
Section titled “Features”- Navigation service — route-based and ViewModel-based navigation with
INavigator - XAML navigation — attached
Navigate.*properties forButton,MenuItem, andToolbarItem - Tab badges — set and clear numeric tab badges by route or ViewModel
- Shell switching — swap the entire Shell at runtime with
SwitchShell(instance or DI-resolved) - Dialog service — alert, confirm, prompt, and action sheet dialogs with
IDialogs - Navigation events —
NavigatingandNavigatedevents with source/destination ViewModel instances - ViewModel lifecycle — appearing/disappearing, navigation confirmation, navigation awareness, and disposal
- Auto BindingContext — ViewModels automatically attached to page binding contexts
- Source generation — eliminates route registration boilerplate, generates strongly-typed navigation extensions and DI registration
- ShinyShell base class — one base class change for deterministic BindingContext assignment on the initial page
- Testable —
INavigatorandIDialogsare injectable and mockable for unit testing
-
Install the NuGet package
Terminal window dotnet add package Shiny.Maui.Shell -
Configure
UseShinyShellin yourMauiProgram.cspublic static class MauiProgram{public static MauiApp CreateMauiApp(){var builder = MauiApp.CreateBuilder();builder.UseMauiApp<App>().UseShinyShell(x => x.Add<MainPage, MainViewModel>(registerRoute: false).Add<AnotherPage, AnotherViewModel>("another")).ConfigureFonts(fonts =>{fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");});return builder.Build();}} -
Update your
AppShellto inherit fromShinyShellAppShell.xaml:
<shiny:ShinyShellx:Class="MyApp.AppShell"xmlns="http://schemas.microsoft.com/dotnet/2021/maui"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"xmlns:shiny="clr-namespace:Shiny;assembly=Shiny.Maui.Shell"xmlns:local="clr-namespace:MyApp"Title="MyApp"><ShellContentTitle="Home"ContentTemplate="{DataTemplate local:MainPage}"Route="MainPage" /></shiny:ShinyShell>AppShell.xaml.cs:
using Shiny;namespace MyApp;public partial class AppShell : ShinyShell{public AppShell(){InitializeComponent();}} -
Inject
INavigatorinto your ViewModels and navigateusing Shiny;public class MainViewModel(INavigator navigator){public async Task GoToDetails(){await navigator.NavigateTo("another");}}
Quick Example
Section titled “Quick Example”// Navigate by route with argumentsawait navigator.NavigateTo("details", ("Id", 42));
// Navigate by ViewModel with strongly typed setupawait navigator.NavigateTo<DetailViewModel>(vm => vm.Id = 42);
// Set a numeric badge on a tabawait navigator.SetTabBadge("Inbox", 3);
// Go back with argumentsawait navigator.GoBack(("Result", "saved"));
// Switch to a different Shell at runtimeawait navigator.SwitchShell<AdminShell>();XAML Navigation
Section titled “XAML Navigation”Navigate attached properties let you trigger route-based navigation directly from XAML without creating a ViewModel command first.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:shiny="clr-namespace:Shiny;assembly=Shiny.Maui.Shell">
<Button Text="Open Detail" shiny:Navigate.Route="Detail" shiny:Navigate.ParameterKey="ItemId" shiny:Navigate.ParameterValue="{Binding SelectedId}" />
<ToolbarItem Text="Home" shiny:Navigate.Route="MainPage" shiny:Navigate.RelativeNavigation="False" /></ContentPage>Navigate currently supports Button, MenuItem, and ToolbarItem.
Tab Badges
Section titled “Tab Badges”Use INavigator to update numeric tab badges for routes that already exist in the active Shell:
await navigator.SetTabBadge("Inbox", 3);await navigator.SetTabBadge<InboxViewModel>(7);await navigator.ClearTabBadge("Inbox");await navigator.ClearTabBadge<InboxViewModel>();Tab badges are supported on Android, iOS, Mac Catalyst, and Windows. Linux and macOS AppKit throw PlatformNotSupportedException.
AI Coding Assistant
Section titled “AI Coding Assistant”Step 1 — Add the marketplace:
claude plugin marketplace add shinyorg/skills Step 2 — Install the plugin:
claude plugin install shiny-maui@shiny Step 1 — Add the marketplace:
copilot plugin marketplace add https://github.com/shinyorg/skills Step 2 — Install the plugin:
copilot plugin install shiny-maui@shiny Next Steps
Section titled “Next Steps”- Navigation — Full
INavigatorAPI reference - Dialogs — Alert, confirm, prompt, and action sheet dialogs
- ViewModel Lifecycle — Lifecycle interfaces and events
- Source Generation — Eliminate boilerplate with attributes