Compartir a través de


Carga de XAML en tiempo de ejecución

Cuando se construye una clase XAML de la interfaz de usuario de aplicaciones multiplataforma de .NET (.NET MAUI), se llama indirectamente a un método LoadFromXaml. Esto ocurre porque el archivo de código subyacente de una clase XAML llama al método InitializeComponent desde su constructor:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }
}

Cuando se compila un proyecto que contiene un archivo XAML, un generador de origen genera un nuevo origen de C# que contiene la definición del InitializeComponent método y lo agrega al objeto de compilación. En el siguiente ejemplo de código se muestra el método InitializeComponent para la clase MainPage:

private void InitializeComponent()
{
    global::Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml(this, typeof(MainPage));
    ...
}

El método InitializeComponent llama al método LoadFromXaml para extraer el binario compilado XAML (o su archivo) del paquete de la aplicación. Después de la extracción, inicializa todos los objetos definidos en XAML, los conecta todos juntos en relaciones de elementos primarios y secundarios, adjunta controladores de eventos definidos en el código a eventos establecidos en el archivo XAML y establece el árbol resultante de objetos como el contenido de la página.

Carga de XAML en tiempo de ejecución

La clase Extensions, en el espacio de nombres Microsoft.Maui.Controls.Xaml, incluye métodos de expansión LoadFromXaml que se pueden usar para cargar y analizar XAML en tiempo de ejecución. Los métodos LoadFromXaml son public y, por lo tanto, pueden llamarse desde aplicaciones .NET MAUI para cargar y analizar XAML en tiempo de ejecución. Esto permite escenarios como una aplicación que descarga XAML desde un servicio web, crea la vista necesaria a partir del XAML y la muestra en la aplicación.

Advertencia

La carga de XAML en tiempo de ejecución tiene un coste de rendimiento significativo y, por lo general, se debe evitar.

Advertencia

Cargar XAML en tiempo de ejecución no es seguro y no debe usarse con recorte completo ni NativeAOT. Se puede hacer que el recorte sea seguro anotando todos los tipos que se pueden cargar en tiempo de ejecución con el DynamicallyAccessedMembers atributo o el DynamicDependency atributo . Sin embargo, esto es muy propenso a errores y no se recomienda. Además, cargar XAML en tiempo de ejecución tiene un costo de rendimiento significativo. Para obtener más información, consulte Recorte de una aplicación MAUI de .NET y implementación de AOT nativa.

El siguiente código muestra un ejemplo de uso sencillo:

string navigationButtonXAML = "<Button Text=\"Navigate\" />";
Button navigationButton = new Button().LoadFromXaml(navigationButtonXAML);
...
stackLayout.Add(navigationButton);

En este ejemplo, se crea una instancia de Button, con su valor de propiedad Text establecido a partir del XAML definido en string. Después, se agrega Button a un objeto StackLayout que se ha definido en el XAML de la página.

Nota:

Los métodos de extensión LoadFromXaml permiten especificar un argumento de tipo genérico. Sin embargo, rara vez es necesario especificar el argumento de tipo, ya que se deducirá del tipo de la instancia en la que funciona.

El método LoadFromXaml se puede usar para inflar cualquier XAML, con el ejemplo siguiente que infla un objeto ContentPage y luego, navega hacia él:

// See the sample for the full XAML string
string pageXAML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<ContentPage xmlns=\"http://schemas.microsoft.com/dotnet/2021/maui\"\nxmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\nx:Class=\"LoadRuntimeXAML.CatalogItemsPage\"\nTitle=\"Catalog Items\">\n</ContentPage>";

ContentPage page = new ContentPage().LoadFromXaml(pageXAML);
await Navigation.PushAsync(page);

Acceso a elementos

Cargar XAML en tiempo de ejecución con el método LoadFromXaml no permite el acceso fuertemente tipado a los elementos XAML que han especificado nombres de objeto en tiempo de ejecución (mediante x:Name). No obstante, estos elementos XAML se pueden recuperar mediante el método FindByName y, después, se puede acceder a ellos si es necesario:

// See the sample for the full XAML string
string pageXAML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<ContentPage xmlns=\"http://schemas.microsoft.com/dotnet/2021/maui\"\nxmlns:x=\"http://schemas.microsoft.com/winfx/2009/xaml\"\nx:Class=\"LoadRuntimeXAML.CatalogItemsPage\"\nTitle=\"Catalog Items\">\n<StackLayout>\n<Label x:Name=\"monkeyName\"\n />\n</StackLayout>\n</ContentPage>";
ContentPage page = new ContentPage().LoadFromXaml(pageXAML);

Label monkeyLabel = page.FindByName<Label>("monkeyName");
monkeyLabel.Text = "Seated Monkey";

En este ejemplo, se infla el XAML de un objeto ContentPage. Este XAML incluye un objeto Label denominado monkeyName, que se recupera mediante el método FindByName, antes de establecer su propiedad Text.