Skip to main content

ContentPage

ContentPage is the foundational building block for screen-based UI in Avalonia. It represents a single page of content and provides built-in support for headers, icons, safe area padding, and command bars. Every screen the user sees is typically a ContentPage (or a subclass of one).

ContentPage is most commonly used as a child of NavigationPage, TabbedPage, or DrawerPage, but it can also be placed directly inside a Window for single-page apps.

How the header displays

The Header property serves different purposes depending on which container hosts the page:

Host controlWhere the header appears
NavigationPageDisplayed in the navigation bar at the top of the screen.
TabbedPageUsed as the tab label.
DrawerPageUsed as the drawer menu item label.
Standalone (in a Window)Not displayed automatically. You must render it yourself if needed.

Useful properties

ContentPage properties

PropertyTypeDefaultDescription
Contentobject?nullThe main content to display on the page.
ContentTemplateIDataTemplate?nullA data template used to render the content.
Headerobject?nullThe page header, displayed in the navigation bar when hosted inside a NavigationPage.
HeaderTemplateIDataTemplate?nullA data template used to render the header.
Iconobject?nullAn icon for the page, displayed in tab bars when hosted inside a TabbedPage.
IconTemplateIDataTemplate?nullA data template used to render the icon.
AutomaticallyApplySafeAreaPaddingbooltrueAutomatically adjusts padding for device safe areas (notches, status bars).
TopCommandBarobject?nullContent displayed in a command bar area above the page content.
BottomCommandBarobject?nullContent displayed in a command bar area below the page content.
SafeAreaPaddingThickness0The current safe area padding applied to the page (read-only at runtime).

Page base properties

These properties are inherited from Page and are available on all page types:

PropertyTypeDefaultDescription
NavigationINavigationinheritedProvides access to the nearest NavigationPage ancestor for push/pop operations.
BackgroundImageIImage?nullAn image displayed behind the page content.
BackgroundImageStretchStretchUniformToFillControls how the background image is stretched to fill the page.

Every Page (including ContentPage) supports lifecycle events that fire during navigation. The events fire in a specific order when a navigation occurs:

EventDescriptionOrder
NavigatingRaised on the current page before navigation begins. Supports cancellation via e.Cancel = true.1
NavigatedFromRaised on the old page after the navigation has completed.2
NavigatedToRaised on the new page after the navigation has completed.3

Overriding lifecycle methods

You can also override the corresponding protected methods instead of subscribing to events:

public class HomePage : ContentPage
{
protected override void OnNavigatedTo(NavigatedToEventArgs args)
{
base.OnNavigatedTo(args);
// Page is now visible, load or refresh data here
}

protected override void OnNavigating(NavigatingEventArgs args)
{
base.OnNavigating(args);
if (HasUnsavedChanges)
{
args.Cancel = true; // Prevent navigation away
}
}

protected override void OnNavigatedFrom(NavigatedFromEventArgs args)
{
base.OnNavigatedFrom(args);
// Page is no longer visible, clean up resources
}
}
note

NavigatedTo is not the same as the Loaded event. Loaded fires once when the control is first added to the visual tree, while NavigatedTo fires every time the page becomes the active page (for example, when returning to it via a back navigation).

Examples

Minimal XAML page

The simplest possible ContentPage with inline content:

<ContentPage xmlns="https://github.com/avaloniaui"
Header="Home">
<TextBlock Text="Hello, world!" Margin="16" />
</ContentPage>

Creating a ContentPage in code

var page = new ContentPage
{
Header = "Home",
Content = new TextBlock
{
Text = "Hello from code!",
Margin = new Thickness(16)
}
};

ContentPage inside a NavigationPage

When hosted in a NavigationPage, the Header is displayed in the navigation bar:

<NavigationPage xmlns="https://github.com/avaloniaui">
<ContentPage Header="Dashboard">
<StackPanel Margin="16" Spacing="8">
<TextBlock Text="Welcome back!" FontSize="24" FontWeight="Bold" />
<Button Content="Go to Details" Click="OnGoToDetails" />
</StackPanel>
</ContentPage>
</NavigationPage>
ContentPage inside a NavigationPage

ContentPage as a window root

For single-page applications, you can place a ContentPage directly inside a Window:

<Window xmlns="https://github.com/avaloniaui"
Title="My App">
<ContentPage>
<StackPanel Margin="16" Spacing="8">
<TextBlock Text="Single-page app" FontSize="24" />
<TextBlock Text="No navigation container needed." />
</StackPanel>
</ContentPage>
</Window>
ContentPage standalone in a Window

Scrollable layout

ContentPage does not include a built-in scroll viewer. Wrap your content in a ScrollViewer if it may overflow:

<ContentPage xmlns="https://github.com/avaloniaui"
Header="Long Content">
<ScrollViewer>
<StackPanel Margin="16" Spacing="8">
<TextBlock Text="Item 1" />
<TextBlock Text="Item 2" />
<TextBlock Text="Item 3" />
<!-- Many more items -->
</StackPanel>
</ScrollViewer>
</ContentPage>

MVVM binding

Bind the page content to a view model using ContentTemplate:

<ContentPage xmlns="https://github.com/avaloniaui"
Header="{Binding Title}"
Content="{Binding}">
<ContentPage.ContentTemplate>
<DataTemplate>
<StackPanel Margin="16" Spacing="8">
<TextBlock Text="{Binding Description}" FontSize="18" />
<TextBlock Text="{Binding Detail}" />
</StackPanel>
</DataTemplate>
</ContentPage.ContentTemplate>
</ContentPage>

TopCommandBar

Display a toolbar above the page content:

<ContentPage xmlns="https://github.com/avaloniaui"
Header="Inbox">
<ContentPage.TopCommandBar>
<StackPanel Orientation="Horizontal" Spacing="4" Margin="8">
<Button Content="Filter" />
<Button Content="Sort" />
</StackPanel>
</ContentPage.TopCommandBar>

<TextBlock Text="Messages go here" Margin="16" />
</ContentPage>
ContentPage with a top command bar

BottomCommandBar

Display a toolbar below the page content:

<ContentPage xmlns="https://github.com/avaloniaui"
Header="Settings">
<ContentPage.BottomCommandBar>
<StackPanel Orientation="Horizontal" Spacing="8" Margin="8">
<Button Content="Save" />
<Button Content="Cancel" />
</StackPanel>
</ContentPage.BottomCommandBar>

<TextBlock Text="Page content goes here" Margin="16" />
</ContentPage>
ContentPage with a bottom command bar

Cancelling navigation

Use the Navigating event or override OnNavigating to prevent the user from leaving a page with unsaved changes:

public class EditPage : ContentPage
{
public bool HasUnsavedChanges { get; set; }

protected override void OnNavigating(NavigatingEventArgs args)
{
base.OnNavigating(args);

if (HasUnsavedChanges)
{
args.Cancel = true;
// Optionally show a confirmation dialog here
}
}
}

Intercepting the system back button

On platforms with a hardware or system back button (Android, browser), Navigating fires before the back action occurs. Cancelling it will also cancel the system back navigation:

protected override void OnNavigating(NavigatingEventArgs args)
{
base.OnNavigating(args);

if (ShouldPreventBack())
{
args.Cancel = true;
}
}

Refreshing data when the page reappears

NavigatedTo fires every time the page becomes active, making it the ideal place to refresh data:

public class OrdersPage : ContentPage
{
protected override async void OnNavigatedTo(NavigatedToEventArgs args)
{
base.OnNavigatedTo(args);
await ViewModel.LoadOrdersAsync();
}
}

Full-bleed layout (disabling safe area padding)

Set AutomaticallyApplySafeAreaPadding to false to let your content extend behind the notch and status bar:

<ContentPage xmlns="https://github.com/avaloniaui"
AutomaticallyApplySafeAreaPadding="False">
<Image Source="avares://MyApp/Assets/hero.jpg"
Stretch="UniformToFill" />
</ContentPage>
ContentPage with safe area padding disabled

Tab with icon

When used inside a TabbedPage, the Header and Icon properties control the tab appearance:

<TabbedPage xmlns="https://github.com/avaloniaui"
TabPlacement="Bottom">
<ContentPage Header="Home" Icon="{StaticResource HomeIcon}">
<TextBlock Text="Home content" Margin="16" />
</ContentPage>
<ContentPage Header="Settings" Icon="{StaticResource SettingsIcon}">
<TextBlock Text="Settings content" Margin="16" />
</ContentPage>
</TabbedPage>
ContentPage used as a tab in TabbedPage

See also