Pages and lifecycle

Compose ContentView pages and respond to loading, appearance, and navigation changes.

A page derives from ContentView and assigns one view tree to Content. The application shell hosts that page in a native view controller and applies its title, safe-area, navigation, search, and toolbar configuration.

Page registration and construction are covered separately in page registration.

[Page]
public sealed class SettingsView : ContentView
{
    public SettingsView()
    {
        Title = "Settings";
        BackgroundStyle = PageBackground.Grouped;

        Content = new ScrollView
        {
            Content = new StackPanel
            {
                Padding = 16,
                Spacing = 12,
                Children =
                {
                    new Label { Text = "General" },
                    new Switch()
                }
            }
        };
    }
}

Assigning Content again removes the old root and installs the new one. Prefer keeping a stable tree and changing bindable properties unless the whole page structure genuinely changes.

Lifecycle callbacks

ContentView exposes six protected callbacks:

  1. OnLoaded runs once when the page is first realized.
  2. OnAppearing runs before it becomes visible.
  3. OnAppeared runs after the transition completes.
  4. OnDisappearing runs before another page covers or removes it.
  5. OnDisappeared runs after that transition completes.
  6. OnUnloaded runs when its native tree is torn down.

Call the base implementation when overriding them. Put visibility-sensitive work in the appearance callbacks and one-time native setup in OnLoaded. A page can appear and disappear several times without unloading.

Guarding unsaved work

Set ConfirmLeave only while the page has changes worth protecting:

public EditPage()
{
    ConfirmLeave = async () =>
    {
        return await Navigator.ConfirmAsync(
            "Discard changes?",
            "Your edits have not been saved.",
            "Yes",
            "No",
            destructive: true);
    };
    Content = ...
}

The guard covers the navigation back button, an interactive sheet dismissal, and tapping outside a popover. Returning false keeps the page open. Leaving the property null avoids installing a guard and keeps the native pop-back gesture available.

Typed pages

Use ContentView<TViewModel> for a page driven by a ViewModel. Its constructor stores the ViewModel, assigns it as BindingContext, and exposes typed Bind helpers:

[Page]
public sealed class ProfileView : ContentView<ProfileViewModel>
{
    public ProfileView(ProfileViewModel viewModel) : base(viewModel)
    {
        Title = Bind(vm => vm.Title);
        Content = new Label { Text = Bind(vm => vm.DisplayName) };
    }
}

The page generator expects a constructor whose first argument is the ViewModel. Other parameters, if any, must be optional so the framework can still create them without context.

Continue with MVVM and binding for one-way, two-way, converted, and list bindings.