Caricamento di XAML in fase di esecuzione in Xamarin.Forms

Lo Xamarin.Forms.Xaml spazio dei nomi include due LoadFromXaml metodi di estensione che possono essere usati per caricare e analizzare XAML in fase di esecuzione.

Background

Quando viene costruita una Xamarin.Forms classe XAML, il LoadFromXaml metodo viene chiamato indirettamente. Ciò si verifica perché il file code-behind per una classe XAML chiama il InitializeComponent metodo dal relativo costruttore:

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

Quando Visual Studio compila un progetto contenente un file XAML, analizza il file XAML per generare un file di codice C# (ad esempio, MainPage.xaml.g.cs) che contiene la definizione del InitializeComponent metodo:

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

Il InitializeComponent metodo chiama il LoadFromXaml metodo per estrarre il file XAML (o il relativo file binario compilato) dalla libreria .NET Standard. Dopo l'estrazione, inizializza tutti gli oggetti definiti nel file XAML, li collega tutti insieme nelle relazioni padre-figlio, associa i gestori eventi definiti nel codice agli eventi impostati nel file XAML e imposta l'albero risultante degli oggetti come contenuto della pagina.

Caricamento di XAML in fase di esecuzione

I LoadFromXaml metodi sono publice quindi possono essere chiamati dalle Xamarin.Forms applicazioni per caricare e analizzare XAML in fase di esecuzione. Ciò consente scenari come il download xaml da un servizio Web da un'applicazione, la creazione della visualizzazione richiesta dal codice XAML e la visualizzazione nell'applicazione.

Avviso

Il caricamento di XAML in fase di esecuzione ha un costo significativo delle prestazioni e in genere deve essere evitato.

L'esempio di codice seguente illustra un utilizzo semplice:

using Xamarin.Forms.Xaml;
...

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

In questo esempio viene creata un'istanza Button di , con il relativo Text valore della proprietà impostato dal codice XAML definito in string. Viene Button quindi aggiunto a un StackLayout oggetto definito nel codice XAML per la pagina.

Nota

I LoadFromXaml metodi di estensione consentono di specificare un argomento di tipo generico. Tuttavia, raramente è necessario specificare l'argomento di tipo, perché verrà dedotto dal tipo dell'istanza in cui opera.

Il LoadFromXaml metodo può essere usato per gonfiare qualsiasi XAML, con l'esempio seguente che gonfia un ContentPage oggetto e quindi passa a esso:

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);

Accesso agli elementi

Il caricamento di XAML in fase di esecuzione con il LoadFromXaml metodo non consente l'accesso fortemente tipizzato agli elementi XAML che hanno specificato nomi di oggetti di runtime (usando x:Name). Tuttavia, questi elementi XAML possono essere recuperati usando il FindByName metodo e quindi accedervi in base alle esigenze:

// 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";
...

In questo esempio il codice XAML per un ContentPage oggetto viene gonfiato. Questo codice XAML include un Label oggetto denominato monkeyName, recuperato usando il metodo , prima che FindByName venga impostata la relativa Text proprietà.