Xamarin.Forms en proyectos nativos de Xamarin

Descargar ejemploDescargar el ejemplo

Normalmente, una Xamarin.Forms aplicación incluye una o varias páginas que derivan de ContentPagey todas las plataformas de un proyecto de biblioteca de .NET Standard o un proyecto compartido comparten estas páginas. Sin embargo, Native Forms permite ContentPageagregar páginas derivadas directamente 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 un 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 hacer referencia desde el código subyacente. Para obtener más información sobre las vistas nativas, vea Vistas nativas.

El proceso para consumir una Xamarin.FormsContentPagepágina derivada de en un proyecto nativo es el siguiente:

  1. Agregue el Xamarin.Forms paquete NuGet al proyecto nativo.
  2. Agregue la ContentPagepágina derivada de 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 ContentPagepágina derivada de mediante la API de navegación nativa.

Xamarin.Forms debe inicializarse llamando al Forms.Init método antes de que un proyecto nativo pueda construir una ContentPagepágina derivada de . La elección de cuándo hacerlo depende principalmente de cuándo es más conveniente en el flujo de la aplicación: se puede realizar al iniciar la aplicación o justo antes de que se construya la ContentPagepágina derivada de . En este artículo y las aplicaciones de ejemplo complementarias, se llama al método al inicio de la Forms.Init 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 Native Forms para consumir ContentPagepáginas derivadas de . 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.

Cuando se usan formularios nativos, Xamarin.Forms las características como DependencyService, MessagingCentery el motor de enlace de datos siguen funcionando. Sin embargo, la navegación por páginas debe realizarse mediante la API de navegación nativa.

iOS

En iOS, la FinishedLaunching invalidación de la clase suele ser el lugar para realizar tareas relacionadas con el inicio de la AppDelegate aplicación. Se llama después de que se haya iniciado la aplicación y normalmente se invalida para configurar la ventana principal y el controlador de vista. En el ejemplo de código siguiente se muestra la AppDelegate clase 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 Forms.Init método .
  • Se crea un nuevo Xamarin.Forms.Application objeto y su diccionario de recursos de nivel de aplicación se establece en un ResourceDictionary que se define en XAML.
  • Una referencia a la AppDelegate clase se almacena en el staticInstance campo . Esto es para proporcionar un mecanismo para que otras clases llamen a métodos definidos en la AppDelegate clase .
  • Se UIWindowcrea , que es el contenedor principal de vistas en aplicaciones nativas de iOS.
  • La FolderPath propiedad se inicializa en una ruta de acceso en el dispositivo donde se almacenarán los datos de nota.
  • NotesPage Se crea un objeto , que es una Xamarin.FormsContentPagepágina derivada de XAML definida en XAML y su elemento primario se establece en el objeto creado Xamarin.Forms.Application 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
  • AppNavigationController Se crea un para administrar la navegación jerárquica. Se trata de una clase de controlador de navegación personalizada, que se deriva de UINavigationController. El AppNavigationController objeto administra una pila de controladores de vista y el UIViewController pasado al constructor se presentará inicialmente cuando se cargue .AppNavigationController
  • El AppNavigationController objeto se establece como el nivel UIViewController superior de UIWindowy UIWindow se 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:

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 Parent propiedad de la página se establezca en el Application objeto .

Al interactuar con la interfaz de usuario, por ejemplo, al pulsar en , +Buttonse producirá 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 staticAppDelegate.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 con UIViewController el método de CreateViewController extensión y establece la Title propiedad de UIViewController. A UIViewController continuación, el método inserta AppNavigationController en .PushViewController Por lo tanto, se mostrará la interfaz de usuario definida en la Xamarin.FormsNoteEntryPage clase , como se muestra en la captura de pantalla siguiente:

La muestra una entrada de nota en un dispositivo móvil.

Cuando se muestra , NoteEntryPage la navegación hacia atrás mostrará para UIViewController la NoteEntryPage clase desde AppNavigationController, devolviendo el usuario a para UIViewController la NotesPage clase . Sin embargo, la obtención 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 AppNavigationController clase invalida el PopViewController método 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 lo hace, se producirá que el UIViewController objeto adjunto y esté Page huérfano.

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 de la clase suele ser el lugar para realizar tareas relacionadas con el inicio de la MainActivity aplicación. En el ejemplo de código siguiente se muestra la MainActivity clase 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 Forms.Init método .
  • Se crea un nuevo Xamarin.Forms.Application objeto y su diccionario de recursos de nivel de aplicación se establece en un ResourceDictionary que se define en XAML.
  • Una referencia a la MainActivity clase se almacena en el staticInstance campo . Esto es para proporcionar un mecanismo para que otras clases llamen a métodos definidos en la MainActivity clase .
  • El Activity contenido se establece a partir de un recurso de diseño. En la aplicación de ejemplo, el diseño consta de un LinearLayout objeto que contiene y Toolbarun que FrameLayout actúa como un contenedor de fragmentos.
  • Toolbar se recupera y se establece como la barra de acciones para Activityy se establece el título de la barra de acciones.
  • La FolderPath propiedad se inicializa en una ruta de acceso en el dispositivo donde se almacenarán los datos de nota.
  • NotesPage Se crea un objeto , que es una Xamarin.FormsContentPagepágina derivada de XAML definida en XAML y su elemento primario se establece en el objeto creado Xamarin.Forms.Application anteriormente.
  • El NotesPage objeto se convierte en mediante Fragment el método de CreateSupportFragment extensión .
  • La SupportFragmentManager clase crea y confirma una transacción que reemplaza la FrameLayout instancia por para Fragment la NotesPage clase .
  • 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 OnCreate método, se mostrará la interfaz de usuario definida en la Xamarin.FormsNotesPage clase , como se muestra en la captura de pantalla siguiente:

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

Importante

Todas las ContentPagepáginas derivadas pueden consumir recursos definidos en el nivel ResourceDictionaryde aplicación , siempre que la Parent propiedad de la página se establezca en el Application objeto .

Al interactuar con la interfaz de usuario, por ejemplo, al pulsar en , +Buttonse producirá 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 staticMainActivity.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 NavigateToNoteEntryPage método convierte la Xamarin.FormsContentPagepágina derivada de en un Fragment objeto con el método de CreateSupportFragment extensión y agrega al Fragment fragmento de la pila de retroceso. Por lo tanto, se mostrará la interfaz de usuario definida en Xamarin.FormsNoteEntryPage , como se muestra en la captura de pantalla siguiente:

La muestra una entrada de nota en un dispositivo móvil con un banner azul.

NoteEntryPage Cuando se muestre , al pulsar la flecha atrás se mostrará el Fragment elemento de la NoteEntryPage pila inversa del fragmento, devolviendo el usuario a para Fragment la NotesPage clase .

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 de retroceso del fragmento. La invalidación controla OnOptionsItemSelected la respuesta para pulsar el botón Atrás:

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 OnOptionsItemSelected invalidación cada vez que se selecciona un elemento en el menú de opciones. Esta implementación extrae 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 de retroceso del fragmento.

Varias actividades

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

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

Elija un archivo

Al insertar una ContentPagepá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 nativa App suele ser el lugar para realizar tareas relacionadas con el inicio de la aplicación. Xamarin.Forms normalmente se inicializa, en Xamarin.Forms 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 OnLaunched método 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 MainPage clase 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 MainPage constructor realiza las siguientes tareas:

  • El almacenamiento en caché está habilitado para la página, por lo que un nuevo MainPage no se construye cuando un usuario vuelve a la página.
  • Una referencia a la MainPage clase se almacena en el staticInstance campo . Esto es para proporcionar un mecanismo para que otras clases llamen a métodos definidos en la MainPage clase .
  • La FolderPath propiedad se inicializa en una ruta de acceso en el dispositivo donde se almacenarán los datos de nota.
  • NotesPage Se crea un objeto , que es una Xamarin.FormsContentPagepágina derivada de XAML definida en XAML y su elemento primario se establece en el objeto creado Xamarin.Forms.Application anteriormente.
  • El NotesPage objeto se convierte en un FrameworkElement mediante el método de CreateFrameworkElement 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 MainPage constructor, se mostrará la interfaz de usuario definida en la Xamarin.FormsNotesPage clase , como se muestra en la captura de pantalla siguiente:

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 Parent propiedad de la página se establezca en el Application objeto .

Al interactuar con la interfaz de usuario, por ejemplo, al pulsar en , +Buttonse producirá 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 staticMainPage.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 Frame.Navigate método , que toma un Page argumento. Xamarin.Forms define un método de Frame.Navigate extensión que toma una ContentPageinstancia de página derivada de . Por lo tanto, cuando se ejecuta el NavigateToNoteEntryPage método, se mostrará la interfaz de usuario definida en , Xamarin.FormsNoteEntryPage como se muestra en la captura de pantalla siguiente:

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

NoteEntryPage Cuando se muestre , al pulsar la flecha atrás se mostrará el FrameworkElement elemento de la NoteEntryPage pila atrás desde la pila posterior de la aplicación, devolviendo el usuario a para FrameworkElement la NotesPage clase .

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 la página se diseña, representa y está lista 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 mediante una llamada 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 del dispositivo. Esto se puede lograr mediante el registro de un controlador de eventos para el BackRequested evento, que se puede realizar en el MainPage constructor:

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

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

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

El OnBackRequested controlador de eventos llama al GoBack método en el marco raíz de la aplicación y establece la BackRequestedEventArgs.Handled propiedad true en 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 AppViewBackButtonVisibility propiedad en uno de los AppViewBackButtonVisibility valores de enumeración, en la App clase :

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

El OnNavigated controlador de eventos, que se ejecuta en respuesta a la Navigated activación del evento, 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 atrás de la aplicación no está vacía o se quita de la barra de título si la pila atrás en la aplicación está vacía.

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