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:Name
de ). 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.