How to use native Frame navigation

Example

The complete sample code can be found in NativeFrameNav on Uno.Samples GitHub repository.

Step-by-step instructions

  1. Create a new Uno Platform application, following the instructions in Get Started guide.

  2. Add two more pages (BlankPage1 and BlankPage2) to the Your_Project_Name project

    Right-click on the Your_Project_Name project -> Add -> New Item... -> Page (Uno Platform Windows App SDK) Repeat once

  3. Modify the content of MainPage.xaml, BlankPage1.xaml, and BlankPage2.xaml pages to the following:

    <Grid toolkit:VisibleBoundsPadding.PaddingMask="Top">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
    
        <CommandBar Grid.Row="0" Content="CHANGE_THE_TEXT_HERE" />
        <StackPanel Grid.Row="1">
            <TextBlock Text="CHANGE_THE_TEXT_HERE" />
        </StackPanel>
    </Grid>
    

    Put a different text for each page: "MainPage", "Content 1", "Content 2".

    Note

    Add xmlns:toolkit="using:Uno.UI.Toolkit" to the <Page> element.

  4. Add a button for forward navigation in the first two pages:

    • MainPage.xaml and BlankPage1.xaml:

      <StackPanel Grid.Row="1">
          <TextBlock Text="Main Content" />
          <Button Content="Next Page" Click="GotoNextPage" />
      </StackPanel>
      
    • MainPage.xaml.cs and BlankPage1.xaml.cs:

      private void GotoNextPage(object sender, RoutedEventArgs e) => Frame.Navigate(typeof(BlankPage1)); // in MainPage
      private void GotoNextPage(object sender, RoutedEventArgs e) => Frame.Navigate(typeof(BlankPage2)); // in BlankPage1
      
  5. (Optionally) Add an AppBarButton to the CommandBar for back navigation in the last two pages for Skia heads:

    • BlankPage1.xaml and BlankPage2.xaml:

      Note

      Here a platform conditional is used to show the AppBarButton on the Skia platforms only. For more information on this feature, check out: platform specific XAML

      <Page ...
            xmlns:skia="http://uno.ui/skia"
            mc:Ignorable="d skia"
            ...>
          <!-- ...  -->
          <CommandBar Grid.Row="0" Content="BlankPage1">
              <CommandBar.PrimaryCommands>
                  <skia:AppBarButton Content="Back" Click="NavigateBack" />
             </CommandBar.PrimaryCommands>
          </CommandBar>
      
    • BlankPage1.xaml.cs, BlankPage2.xaml.cs:

      private void NavigateBack(object sender, RoutedEventArgs e) => Frame.GoBack(); // in both pages
      
  6. Enable native frame navigation in App.cs or App.xaml.cs:

    public App()
    {
        InitializeLogging();
    
    #if __IOS__ || __ANDROID__
        Uno.UI.FeatureConfiguration.Style.ConfigureNativeFrameNavigation();
    #endif
    
        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }
    
  7. Add some extra setups for navigation:

    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        /* existing code... */
    
        ConfigureNavigation();
    }
    
    private void ConfigureNavigation()
    {
    #if __ANDROID__ || __WASM__
        var frame = (Frame)_window.Content;
        var manager = Windows.UI.Core.SystemNavigationManager.GetForCurrentView();
    
        // Toggle the visibility of back button based on if the frame can navigate back.
        // Setting it to visible has the follow effect on the platform:
        // - uwp: show a `<-` back button on the title bar
        // - wasm: add a dummy entry in the browser back stack
        frame.Navigated += (s, e) => manager.AppViewBackButtonVisibility = frame.CanGoBack
            ? Windows.UI.Core.AppViewBackButtonVisibility.Visible
            : Windows.UI.Core.AppViewBackButtonVisibility.Collapsed;
    
        // On some platforms, the back navigation request needs to be hooked up to the back navigation of the Frame.
        // These requests can come from:
        // - uwp: title bar back button
        // - droid: CommandBar back button, os back button/gesture
        // - wasm: browser back button
        manager.BackRequested += (s, e) =>
        {
            if (frame.CanGoBack)
            {
                frame.GoBack();
    
                e.Handled = true;
            }
        };
    #endif
    }
    

Additional Resources