| MAUI-CollectionView :👈 | 👉:MAUI-ContentPage-ContentView |
.NET MAUI ShellContent vs Pages |
In .NET MAUI Shell, ShellContent and Pages (ContentPage, TabbedPage, etc.) serve different purposes and exist at different levels of the navigation hierarchy. Although both are related to navigation,only a Page represents the actual screen displayed to the user.
Many developers initially confuse them because both ultimately display UI, but they play very different roles.
Think of Shell as a navigation framework
Simple analogy:
The guest stays in the room (Page), not the room number (ShellContent)
Shell ├── FlyoutItem │ ├── Tab │ │ └── ShellContent │ │ └── HomePage │ └── Tab │ └── ShellContent │ └── SettingsPage
<Shell>
<FlyoutItem Title="Home">
<Tab>
<ShellContent
Title="Dashboard"
ContentTemplate="{DataTemplate local:HomePage}" />
</Tab>
</FlyoutItem>
</Shell>
In this example:
A ShellContent is a Shell navigation item that hosts a Page. It does not contain the actual user interface.
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:HomePage}" />
This tells Shell to display HomePage when the user navigates to this item.
A Page is the actual screen that users interact with.
public partial class HomePage : ContentPage
{
public HomePage()
{
InitializeComponent();
}
}
<ContentPage> <VerticalStackLayout> <Label Text="Welcome Home" FontSize="30" /> </VerticalStackLayout> </ContentPage>
<Shell>
<TabBar>
<ShellContent
Route="home"
Title="Home"
ContentTemplate="{DataTemplate local:HomePage}" />
<ShellContent
Route="settings"
Title="Settings"
ContentTemplate="{DataTemplate local:SettingsPage}" />
</TabBar>
</Shell>
Navigation Structure:
TabBar ├── Home │ └── HomePage └── Settings └── SettingsPage
The recommended approach is to use ContentTemplate.
<ShellContent
ContentTemplate="{DataTemplate local:HomePage}" />
<ShellContent> <local:HomePage /> </ShellContent>
Using DataTemplate enables lazy loading. Pages are created only when needed, improving startup performance and memory usage.
<Tab Title="Sales">
<ShellContent
Title="Orders"
ContentTemplate="{DataTemplate local:OrdersPage}" />
<ShellContent
Title="Invoices"
ContentTemplate="{DataTemplate local:InvoicesPage}" />
</Tab>
Structure:
Sales ├── Orders └── Invoices
Use ShellContent for primary application navigation.
<FlyoutItem Title="Reports">
<ShellContent
ContentTemplate="{DataTemplate local:ReportsPage}" />
</FlyoutItem>
<TabBar>
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:HomePage}" />
<ShellContent
Title="Profile"
ContentTemplate="{DataTemplate local:ProfilePage}" />
</TabBar>
Login pages, popup-style screens, and temporary flows should not normally be ShellContent items.
await Shell.Current.Navigation.PushModalAsync( new LoginPage());
These typically should not appear in the Flyout or TabBar.
These are usually navigated programmatically instead of being ShellContent items.
<ShellContent
Route="customers"
ContentTemplate="{DataTemplate local:CustomersPage}" />
Visible in the application's navigation structure.
Routing.RegisterRoute( nameof(CustomerDetailsPage), typeof(CustomerDetailsPage));
Navigation:
await Shell.Current.GoToAsync( nameof(CustomerDetailsPage));
Registered routes are hidden from Flyout and TabBar navigation.
Good:
Avoid:
<ShellContent
ContentTemplate="{DataTemplate local:HomePage}" />
AppShell should define navigation only. Business logic belongs in:
Routing.RegisterRoute( nameof(OrderDetailsPage), typeof(OrderDetailsPage));
Good:
customers orders reports settings
Avoid:
page1 page2 page3
AppShell │ ├── Dashboard ├── Shipments ├── Customers ├── Reports ├── Settings │ └── Hidden Routes ├── ShipmentDetailsPage ├── CustomerEditPage └── ReportViewerPage
Main sections use ShellContent. Detail and edit screens use registered routes.
Use ShellContent when a page should be part of the application's permanent navigation structure such as Flyout menus or bottom tabs.
Use a Page with a registered route when the page is temporary, detail-oriented, modal, or launched from another page.
Summary: ShellContent defines where a page appears in navigation, while the Page defines what the user sees and interacts with.
| MAUI-CollectionView :👈 | 👉:MAUI-ContentPage-ContentView |