Compartir vía


Xamarin.Forms en proyectos nativos de Xamarin

Normalmente, una Xamarin.Forms aplicación incluye una o varias páginas que derivan de ContentPage, y todas las plataformas de un proyecto de biblioteca de .NET Standard o un proyecto compartido comparten estas páginas. Sin embargo, Native Forms permite agregar páginas derivadas de ContentPagedirectamente a aplicaciones nativas de Xamarin.iOS, Xamarin.Android y UWP. En comparación con que el proyecto nativo consume ContentPagepáginas derivadas de un proyecto de biblioteca de .NET Standard o proyecto compartido, la ventaja de agregar páginas directamente a proyectos nativos es que las páginas se pueden ampliar con vistas nativas. A continuación, las vistas nativas se pueden denominar en XAML con x:Name y se hace referencia a las vistas nativas desde el código subyacente. Para obtener más información sobre las vistas nativas, vea Vistas nativas.

El proceso para consumir una página derivada de un Xamarin.FormsContentPageproyecto nativo es el siguiente:

  1. Agregue el paquete NuGet Xamarin.Forms al proyecto nativo.
  2. Agregue la página derivada de ContentPage, y las dependencias al proyecto nativo.
  3. Llame al método Forms.Init.
  4. Construya una instancia de la ContentPagepágina derivada de y conviértala en el tipo nativo adecuado mediante uno de los métodos de extensión siguientes: CreateViewController para iOS, CreateSupportFragment para Android o CreateFrameworkElement para UWP.
  5. Vaya a la representación de tipo nativo de la página derivada de ContentPagemediante la API de navegación nativa.

Xamarin.Forms debe inicializarse llamando al método Forms.Init antes de que un proyecto nativo pueda construir una página derivada de ContentPage. Elegir cuándo hacerlo depende principalmente de cuándo es más conveniente en el flujo de la aplicación, que se puede realizar al iniciar la aplicación o justo antes de que se construya la página derivada ContentPage. En este artículo, y las aplicaciones de ejemplo complementarias, se llama al método Forms.Init en el inicio de la aplicación.

Nota:

La solución de aplicación de ejemplo NativeForms no contiene ningún Xamarin.Forms proyecto. En su lugar, consta de un proyecto de Xamarin.iOS, un proyecto de Xamarin.Android y un proyecto de UWP. Cada proyecto es un proyecto nativo que usa Formularios nativos para consumir ContentPagepáginas derivadas. Sin embargo, no hay ninguna razón por la que los proyectos nativos no podían consumir ContentPagepáginas derivadas de un proyecto de biblioteca de .NET Standard o un proyecto compartido.

Al usar formularios nativos, Xamarin.Forms las características como DependencyService, MessagingCenter, y el motor de enlace de datos siguen funcionando. Sin embargo, la navegación de páginas debe realizarse mediante la API de navegación nativa.

iOS

En iOS, el FinishedLaunching invalidación en la clase AppDelegate suele ser el lugar para realizar tareas relacionadas con el inicio de la aplicación. Se llama después de iniciar la aplicación y normalmente se reemplaza para configurar la ventana principal y el controlador de vista. En el ejemplo de código siguiente se muestra la clase AppDelegate en la aplicación de ejemplo:

[Register("AppDelegate")]
public class AppDelegate : UIApplicationDelegate
{
    public static AppDelegate Instance;
    UIWindow _window;
    AppNavigationController _navigation;

    public static string FolderPath { get; private set; }

    public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
    {
        Forms.Init();

        // Create app-level resource dictionary.
        Xamarin.Forms.Application.Current = new Xamarin.Forms.Application();
        Xamarin.Forms.Application.Current.Resources = new MyDictionary();

        Instance = this;
        _window = new UIWindow(UIScreen.MainScreen.Bounds);

        UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes
        {
            TextColor = UIColor.Black
        });

        FolderPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));

        NotesPage notesPage = new NotesPage()
        {
            // Set the parent so that the app-level resource dictionary can be located.
            Parent = Xamarin.Forms.Application.Current
        };

        UIViewController notesPageController = notesPage.CreateViewController();
        notesPageController.Title = "Notes";

        _navigation = new AppNavigationController(notesPageController);

        _window.RootViewController = _navigation;
        _window.MakeKeyAndVisible();

        notesPage.Parent = null;
        return true;
    }
    // ...
}

El método FinishedLaunching realiza las siguientes tareas:

  • Xamarin.Forms se inicializa llamando al métodoForms.Init.
  • Se crea un nuevo Xamarin.Forms.Application objeto y su diccionario de recursos de nivel de aplicación se establece en un ResourceDictionary objeto definido en XAML.
  • Una referencia a la AppDelegate clase se almacena en el static Instance campo . Se trata de proporcionar un mecanismo para que otras clases llamen a métodos definidos en la AppDelegate clase.
  • Se UIWindowcrea el, que es el contenedor principal para las vistas en aplicaciones nativas de iOS.
  • La propiedad FolderPath se inicializa en una ruta de acceso en el dispositivo donde se almacenarán los datos de nota.
  • Se crea un objeto NotesPage, que es una página derivada de Xamarin.FormsContentPage definida en XAML y su elemento primario se establece en el objeto Xamarin.Forms.Application creado anteriormente.
  • El NotesPage objeto se convierte en mediante UIViewController el método de CreateViewController extensión.
  • La Title propiedad de UIViewController se establece, que se mostrará en UINavigationBar.
  • Se crea un AppNavigationController para administrar la navegación jerárquica. Se trata de una clase de controlador de navegación personalizada, que deriva de UINavigationController. El AppNavigationController objeto administra una pila de controladores de vista y el UIViewController pasado al constructor se presentará inicialmente cuando AppNavigationController se cargue.
  • El AppNavigationController objeto se establece como el nivel UIViewController superior de UIWindow, y se UIWindow establece como la ventana de clave de la aplicación y se hace visible.
  • La Parent propiedad del NotesPage objeto se establece en null, para evitar una pérdida de memoria.

Una vez ejecutado el FinishedLaunching método, se mostrará la interfaz de usuario definida en la Xamarin.FormsNotesPage clase, como se muestra en la captura de pantalla siguiente:

Captura de pantalla que muestra una pantalla Notas en un dispositivo móvil.

Importante

Todas las ContentPagepáginas derivadas pueden consumir recursos definidos en el nivel ResourceDictionaryde aplicación, siempre que la propiedadParent de la página esté establecida en el objeto Application.

La interacción con la interfaz de usuario, por ejemplo, al pulsar en , + Buttondará como resultado el siguiente controlador de eventos en la ejecución del NotesPage código subyacente:

void OnNoteAddedClicked(object sender, EventArgs e)
{
    AppDelegate.Instance.NavigateToNoteEntryPage(new Note());
}

El static AppDelegate.Instance campo permite invocar el AppDelegate.NavigateToNoteEntryPage método , que se muestra en el ejemplo de código siguiente:

public void NavigateToNoteEntryPage(Note note)
{
    NoteEntryPage noteEntryPage = new NoteEntryPage
    {
        BindingContext = note,
        // Set the parent so that the app-level resource dictionary can be located.
        Parent = Xamarin.Forms.Application.Current
    };

    var noteEntryViewController = noteEntryPage.CreateViewController();
    noteEntryViewController.Title = "Note Entry";

    _navigation.PushViewController(noteEntryViewController, true);
    noteEntryPage.Parent = null;
}

El NavigateToNoteEntryPage método convierte la Xamarin.FormsContentPagepágina derivada de en UIViewController con el CreateViewController método de extensión y establece la Title propiedad de UIViewController. A UIViewController continuación, el método inserta AppNavigationController el PushViewController control. Por lo tanto, se mostrará la interfaz de usuario definida en la Xamarin.FormsNoteEntryPage clase, como se muestra en la captura de pantalla siguiente:

Captura de pantalla que muestra una entrada de nota en un dispositivo móvil.

Cuando se muestra la NoteEntryPage, navegación hacia atrás mostrará el UIViewController de la clase NoteEntryPage de la AppNavigationController, devolviendo el usuario al UIViewController de la clase NotesPage. Sin embargo, la salida de un UIViewController elemento de la pila de navegación nativa de iOS no elimina automáticamente el UIViewController objeto adjunto y Page. Por lo tanto, la clase AppNavigationController invalida el método PopViewController para eliminar controladores de vista en la navegación hacia atrás:

public class AppNavigationController : UINavigationController
{
    //...
    public override UIViewController PopViewController(bool animated)
    {
        UIViewController topView = TopViewController;
        if (topView != null)
        {
            // Dispose of ViewController on back navigation.
            topView.Dispose();
        }
        return base.PopViewController(animated);
    }
}

La PopViewController invalidación llama al Dispose método en el UIViewController objeto que se ha extraído de la pila de navegación nativa de iOS. Si no se hace esto, se producirá que el UIViewController objeto adjunto y el objeto adjunto Page estén huérfanos.

Importante

Los objetos huérfanos no se pueden recopilar como elementos no utilizados, por lo que se produce una pérdida de memoria.

Android

En Android, la OnCreate invalidación en la clase MainActivitysuele ser el lugar para realizar tareas relacionadas con el inicio de la aplicación. En el ejemplo de código siguiente se muestra la clase MainActivity en la aplicación de ejemplo:

public class MainActivity : AppCompatActivity
{
    public static string FolderPath { get; private set; }

    public static MainActivity Instance;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        Forms.Init(this, bundle);

        // Create app-level resource dictionary.
        Xamarin.Forms.Application.Current = new Xamarin.Forms.Application();
        Xamarin.Forms.Application.Current.Resources = new MyDictionary();

        Instance = this;

        SetContentView(Resource.Layout.Main);
        var toolbar = FindViewById<Toolbar>(Resource.Id.toolbar);
        SetSupportActionBar(toolbar);
        SupportActionBar.Title = "Notes";

        FolderPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData));

        NotesPage notesPage = new NotesPage()
        {
            // Set the parent so that the app-level resource dictionary can be located.
            Parent = Xamarin.Forms.Application.Current
        };
        AndroidX.Fragment.App.Fragment notesPageFragment = notesPage.CreateSupportFragment(this);

        SupportFragmentManager
            .BeginTransaction()
            .Replace(Resource.Id.fragment_frame_layout, mainPage)
            .Commit();
        //...

        notesPage.Parent = null;
    }
    ...
}

El método OnCreate realiza las siguientes tareas:

  • Xamarin.Forms se inicializa llamando al métodoForms.Init.
  • Se crea un nuevo Xamarin.Forms.Application objeto y su diccionario de recursos de nivel de aplicación se establece en un ResourceDictionary objeto definido en XAML.
  • Una referencia a la MainActivity clase se almacena en el static Instance campo . Se trata de proporcionar un mecanismo para que otras clases llamen a métodos definidos en la MainActivity clase.
  • El Activity contenido se establece desde un recurso de diseño. En la aplicación de ejemplo, el diseño consta de un LinearLayout que contiene un Toolbar, y un FrameLayout para actuar como un contenedor de fragmentos.
  • El Toolbar se recupera y se establece como la barra de acciones de la Activity, y se establece el título de la barra de acciones.
  • La propiedad FolderPath se inicializa en una ruta de acceso en el dispositivo donde se almacenarán los datos de nota.
  • Se crea un objeto NotesPage, que es una página derivada de Xamarin.FormsContentPage definida en XAML y su elemento primario se establece en el objeto Xamarin.Forms.Application creado anteriormente.
  • El NotesPage objeto se convierte en mediante Fragment el método de CreateSupportFragment extensión.
  • La clase SupportFragmentManager crea y confirma una transacción que reemplaza la instancia de FrameLayout por el Fragment de la clase NotesPage.
  • La Parent propiedad del NotesPage objeto se establece en null, para evitar una pérdida de memoria.

Para obtener más información sobre los fragmentos, vea Fragmentos.

Una vez ejecutado el método OnCreate, se mostrará la interfaz de usuario definida en la clase Xamarin.FormsNotesPage, como se muestra en la captura de pantalla siguiente:

Captura de pantalla que muestra una pantalla Notas en un dispositivo móvil con un banner azul y texto de nota en color.

Importante

Todas las ContentPagepáginas derivadas pueden consumir recursos definidos en el nivel ResourceDictionaryde aplicación, siempre que la propiedadParent de la página esté establecida en el objeto Application.

La interacción con la interfaz de usuario, por ejemplo, al pulsar en , + Buttondará como resultado el siguiente controlador de eventos en la ejecución del NotesPage código subyacente:

void OnNoteAddedClicked(object sender, EventArgs e)
{
    MainActivity.Instance.NavigateToNoteEntryPage(new Note());
}

El static MainActivity.Instance campo permite invocar el MainActivity.NavigateToNoteEntryPage método , que se muestra en el ejemplo de código siguiente:

public void NavigateToNoteEntryPage(Note note)
{
    NoteEntryPage noteEntryPage = new NoteEntryPage
    {
        BindingContext = note,
        // Set the parent so that the app-level resource dictionary can be located.
        Parent = Xamarin.Forms.Application.Current
    };

    AndroidX.Fragment.App.Fragment noteEntryFragment = noteEntryPage.CreateSupportFragment(this);
    SupportFragmentManager
        .BeginTransaction()
        .AddToBackStack(null)
        .Replace(Resource.Id.fragment_frame_layout, noteEntryFragment)
        .Commit();

    noteEntryPage.Parent = null;
}

El método NavigateToNoteEntryPage convierte la página derivada de Xamarin.FormsContentPageen un Fragment con el método de extensión CreateSupportFragment y agrega el Fragment a la pila de retroceso del fragmento. Por lo tanto, se mostrará la interfaz de usuario definida en el Xamarin.FormsNoteEntryPage, como se muestra en la captura de pantalla siguiente:

Captura de pantalla que muestra una entrada de nota en un dispositivo móvil con un banner azul.

Cuando se muestra NoteEntryPage, al pulsar la flecha atrás se abrirá el Fragment para el NoteEntryPage de la pila de retroceso del fragmento, devolviendo el usuario al Fragment de la clase NotesPage.

Habilitación de la compatibilidad con la navegación hacia atrás

La SupportFragmentManager clase tiene un BackStackChanged evento que se activa cada vez que cambia el contenido de la pila de retroceso del fragmento. El OnCreate método de la MainActivity clase contiene un controlador de eventos anónimo para este evento:

SupportFragmentManager.BackStackChanged += (sender, e) =>
{
    bool hasBack = SupportFragmentManager.BackStackEntryCount > 0;
    SupportActionBar.SetHomeButtonEnabled(hasBack);
    SupportActionBar.SetDisplayHomeAsUpEnabled(hasBack);
    SupportActionBar.Title = hasBack ? "Note Entry" : "Notes";
};

Este controlador de eventos muestra un botón Atrás en la barra de acciones siempre que haya una o varias Fragment instancias en la pila posterior del fragmento. La respuesta para pulsar el botón Atrás se controla mediante la OnOptionsItemSelected invalidación:

public override bool OnOptionsItemSelected(Android.Views.IMenuItem item)
{
    if (item.ItemId == global::Android.Resource.Id.Home && SupportFragmentManager.BackStackEntryCount > 0)
    {
        SupportFragmentManager.PopBackStack();
        return true;
    }
    return base.OnOptionsItemSelected(item);
}

Se llama a la invalidación OnOptionsItemSelected cada vez que se selecciona un elemento en el menú de opciones. Esta implementación muestra el fragmento actual de la pila de retroceso del fragmento, siempre que se haya seleccionado el botón Atrás y que haya una o varias Fragment instancias en la pila posterior del fragmento.

Varias actividades

Cuando una aplicación se compone de varias actividades, ContentPagelas páginas derivadas se pueden insertar en cada una de las actividades. En este escenario, Forms.Init solo se debe llamar al método en la OnCreate invalidación del primero Activity que inserta un Xamarin.FormsContentPage. Sin embargo, esto tiene el siguiente impacto:

  • El valor de Xamarin.Forms.Color.Accent se tomará del Activity que llamó al Forms.Init método.
  • El valor de Xamarin.Forms.Application.Current se asociará al Activity que llamó al Forms.Init método.

Elija un archivo

Al insertar una ContentPage página derivada de que usa un WebView que necesita admitir un botón Activity HTML "Elegir archivo", deberá invalidar el OnActivityResult método:

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);
    ActivityResultCallbackRegistry.InvokeCallback(requestCode, resultCode, data);
}

UWP

En UWP, la clase App nativa suele ser el lugar para realizar tareas relacionadas con el inicio de la aplicación. Xamarin.Forms normalmente se inicializa, en Xamarin.Forms las aplicaciones para UWP, en la OnLaunched invalidación de la clase nativa App, para pasar el LaunchActivatedEventArgs argumento al Forms.Init método. Por este motivo, las aplicaciones nativas para UWP que consumen una Xamarin.FormsContentPagepágina derivada de pueden llamar más fácilmente al Forms.Init método desde el App.OnLaunched método:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    // ...
    Xamarin.Forms.Forms.Init(e);

    // Create app-level resource dictionary.
    Xamarin.Forms.Application.Current = new Xamarin.Forms.Application();
    Xamarin.Forms.Application.Current.Resources = new MyDictionary();

    // ...
}

Además, el método OnLaunched también puede crear cualquier diccionario de recursos de nivel de aplicación que requiera la aplicación.

De forma predeterminada, la clase nativa App inicia la MainPage clase como la primera página de la aplicación. En el ejemplo de código siguiente se muestra la clase MainPage en la aplicación de ejemplo:

public sealed partial class MainPage : Page
{
    NotesPage notesPage;
    NoteEntryPage noteEntryPage;

    public static MainPage Instance;
    public static string FolderPath { get; private set; }

    public MainPage()
    {
        this.NavigationCacheMode = NavigationCacheMode.Enabled;
        Instance = this;
        FolderPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData));

        notesPage = new Notes.UWP.Views.NotesPage
        {
            // Set the parent so that the app-level resource dictionary can be located.
            Parent = Xamarin.Forms.Application.Current
        };
        this.Content = notesPage.CreateFrameworkElement();
        // ...
        notesPage.Parent = null;    
    }
    // ...
}

El constructor MainPage realiza las siguientes tareas:

  • El almacenamiento en caché está habilitado para la página, de modo que un nuevo MainPage no se construya cuando un usuario vuelva a la página.
  • Una referencia a la MainPage clase se almacena en el static Instance campo . Se trata de proporcionar un mecanismo para que otras clases llamen a métodos definidos en la MainPage clase.
  • La propiedad FolderPath se inicializa en una ruta de acceso en el dispositivo donde se almacenarán los datos de nota.
  • Se crea un objeto NotesPage, que es una página derivada de Xamarin.FormsContentPage definida en XAML y su elemento primario se establece en el objeto Xamarin.Forms.Application creado anteriormente.
  • El NotesPage objeto se convierte en un FrameworkElement mediante el CreateFrameworkElement método de extensión y, a continuación, se establece como el contenido de la MainPage clase.
  • La Parent propiedad del NotesPage objeto se establece en null, para evitar una pérdida de memoria.

Una vez ejecutado el constructor MainPage, se mostrará la interfaz de usuario definida en la clase Xamarin.FormsNotesPage, como se muestra en la captura de pantalla siguiente:

Captura de pantalla que muestra una página Notas con notas y fecha y hora.

Importante

Todas las ContentPagepáginas derivadas pueden consumir recursos definidos en el nivel ResourceDictionaryde aplicación, siempre que la propiedadParent de la página esté establecida en el objeto Application.

La interacción con la interfaz de usuario, por ejemplo, al pulsar en , + Buttondará como resultado el siguiente controlador de eventos en la ejecución del NotesPage código subyacente:

void OnNoteAddedClicked(object sender, EventArgs e)
{
    MainPage.Instance.NavigateToNoteEntryPage(new Note());
}

El static MainPage.Instance campo permite invocar el MainPage.NavigateToNoteEntryPage método , que se muestra en el ejemplo de código siguiente:

public void NavigateToNoteEntryPage(Note note)
{
    noteEntryPage = new Notes.UWP.Views.NoteEntryPage
    {
        BindingContext = note,
        // Set the parent so that the app-level resource dictionary can be located.
        Parent = Xamarin.Forms.Application.Current
    };
    this.Frame.Navigate(noteEntryPage);
    noteEntryPage.Parent = null;
}

La navegación en UWP se realiza normalmente con el método Frame.Navigate, que toma un argumento Page. Xamarin.Forms define un método de extensión Frame.Navigate que toma una instancia de página derivada ContentPage. Por lo tanto, cuando se ejecuta el método NavigateToNoteEntryPage, se mostrará la interfaz de usuario definida en el Xamarin.FormsNoteEntryPage, como se muestra en la captura de pantalla siguiente:

Captura de pantalla que muestra una página Notas con un cuadro de texto con una nota especificada.

Cuando se muestre el NoteEntryPage, al pulsar la flecha atrás se abrirá el FrameworkElement de la NoteEntryPage de la pila de retroceso de la aplicación, devolviendo el usuario al FrameworkElement de la clase NotesPage.

Habilitación de la compatibilidad con el cambio de tamaño de página

Cuando se cambia el tamaño de la ventana de la aplicación para UWP, también se debe cambiar el tamaño del Xamarin.Forms contenido. Esto se logra mediante el registro de un controlador de eventos para el Loaded evento, en el MainPage constructor:

public MainPage()
{
    // ...
    this.Loaded += OnMainPageLoaded;
    // ...
}

El Loaded evento se desencadena cuando se diseña, representa y prepara la página para la interacción, y ejecuta el OnMainPageLoaded método en respuesta:

void OnMainPageLoaded(object sender, RoutedEventArgs e)
{
    this.Frame.SizeChanged += (o, args) =>
    {
        if (noteEntryPage != null)
            noteEntryPage.Layout(new Xamarin.Forms.Rectangle(0, 0, args.NewSize.Width, args.NewSize.Height));
        else
            notesPage.Layout(new Xamarin.Forms.Rectangle(0, 0, args.NewSize.Width, args.NewSize.Height));
    };
}

El OnMainPageLoaded método registra un controlador de eventos anónimo para el Frame.SizeChanged evento, que se genera cuando las ActualHeight propiedades o ActualWidth cambian en Frame. En respuesta, se cambia el tamaño del Xamarin.Forms contenido de la página activa llamando al Layout método.

Habilitación de la compatibilidad con la navegación hacia atrás

En UWP, las aplicaciones deben habilitar la navegación hacia atrás para todos los botones atrás de hardware y software, en diferentes factores de forma de dispositivo. Esto se puede lograr mediante el registro de un controlador de eventos para el evento BackRequested, que se puede realizar en el constructor MainPage:

public MainPage()
{
    // ...
    SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
}

Cuando se inicia la aplicación, el método GetForCurrentView recupera el objeto SystemNavigationManager asociado a la vista actual y, a continuación, registra un controlador de eventos para el evento BackRequested. La aplicación solo recibe este evento si es la aplicación en primer plano y, en respuesta, llama al controlador de eventos OnBackRequested:

void OnBackRequested(object sender, BackRequestedEventArgs e)
{
    Frame rootFrame = Window.Current.Content as Frame;
    if (rootFrame.CanGoBack)
    {
        e.Handled = true;
        rootFrame.GoBack();
        noteEntryPage = null;
    }
}

El controlador de eventos OnBackRequested llama al método GoBack en el marco raíz de la aplicación y establece la propiedad BackRequestedEventArgs.Handled en true para marcar el evento como controlado. Si no se marca el evento como controlado, se podría omitir el evento.

La aplicación elige si se va a mostrar un botón Atrás en la barra de título. Esto se logra estableciendo la propiedad AppViewBackButtonVisibility en uno de los valores de enumeración AppViewBackButtonVisibility, en la clase App:

void OnNavigated(object sender, NavigationEventArgs e)
{
    SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
        ((Frame)sender).CanGoBack ? AppViewBackButtonVisibility.Visible : AppViewBackButtonVisibility.Collapsed;
}

El controlador de eventos OnNavigated, que se ejecuta en respuesta a la activación del evento Navigated, actualiza la visibilidad del botón Atrás de la barra de título cuando se produce la navegación por páginas. Esto garantiza que el botón Atrás de la barra de título esté visible si la pila de retroceso de la aplicación no está vacía o se quita de la barra de título si la pila de retroceso en la aplicación está vacía.

Para obtener más información sobre la compatibilidad con la navegación inversa en UWP, vea Historial de navegación y navegación hacia atrás para aplicaciones para UWP.