Chargement de XAML au moment de l’exécution dans Xamarin.Forms

L’espace Xamarin.Forms.Xaml de noms comprend deux LoadFromXaml méthodes d’extension qui peuvent être utilisées pour charger et analyser XAML au moment de l’exécution.

Background

Lorsqu’une Xamarin.Forms classe XAML est construite, la LoadFromXaml méthode est indirectement appelée. Cela se produit parce que le fichier code-behind d’une classe XAML appelle la méthode InitializeComponent à partir de son constructeur :

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

Lorsque Visual Studio génère un projet contenant un fichier XAML, il analyse le fichier XAML pour générer un fichier de code C# (par exemple, MainPage.xaml.g.cs) qui contient la définition de la InitializeComponent méthode :

private void InitializeComponent()
{
    global::Xamarin.Forms.Xaml.Extensions.LoadFromXaml(this, typeof(MainPage));
    ...
}

La InitializeComponent méthode appelle la LoadFromXaml méthode pour extraire le fichier XAML (ou son fichier binaire compilé) à partir de la bibliothèque .NET Standard. Après l’extraction, il initialise tous les objets définis dans le fichier XAML, les connecte tous ensemble dans les relations parent-enfant, attache des gestionnaires d’événements définis dans le code aux événements définis dans le fichier XAML et définit l’arborescence résultante des objets comme contenu de la page.

Chargement du code XAML au moment de l’exécution

Les LoadFromXaml méthodes sont public, et par conséquent peuvent être appelées à partir d’applications Xamarin.Forms pour charger, et analyser XAML au moment de l’exécution. Cela permet des scénarios tels qu’un téléchargement d’application XAML à partir d’un service web, la création de l’affichage requis à partir du code XAML et son affichage dans l’application.

Avertissement

Le chargement de XAML au moment de l’exécution a un coût important sur les performances et doit généralement être évité.

L’exemple de code suivant montre une utilisation simple :

using Xamarin.Forms.Xaml;
...

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

Dans cet exemple, une instance Button est créée avec sa valeur de propriété Text définie à partir du XAML défini dans string. Le Button est ensuite ajouté à un StackLayout qui a été défini dans le XAML de la page.

Remarque

Les méthodes d’extension LoadFromXaml permettent à un argument de type générique d’être spécifié. Toutefois, il est rarement nécessaire de spécifier l’argument de type, car il sera déduit du type de l’instance sur laquelle il fonctionne.

La méthode LoadFromXaml peut être utilisée pour remplir (« inflate ») n’importe quel XAML, avec l’exemple suivant qui remplit un ContentPage, puis y accède :

using Xamarin.Forms.Xaml;
...

// See the sample for the full XAML string
string pageXAML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<ContentPage xmlns=\"http://xamarin.com/schemas/2014/forms\"\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);

Accès aux éléments

Le chargement de XAML au moment de l’exécution avec la LoadFromXaml méthode n’autorise pas l’accès fortement typé aux éléments XAML qui ont spécifié des noms d’objets runtime (à l’aide x:Namede ). Toutefois, ces éléments XAML peuvent être récupérés à l’aide de la méthode FindByName, puis accessibles si besoin :

// See the sample for the full XAML string
string pageXAML = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<ContentPage xmlns=\"http://xamarin.com/schemas/2014/forms\"\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";
...

Dans cet exemple, le XAML d’un ContentPage est rempli. Ce XAML inclut un Label appelé monkeyName, qui est récupéré à l’aide de la méthode FindByName avant que sa propriété Text ne soit définie.