Načítání XAML za běhu v Xamarin.Forms
Obor Xamarin.Forms.Xaml
názvů obsahuje dvě LoadFromXaml
rozšiřující metody, které je možné použít k načtení, a parsovat XAML za běhu.
Pozadí
Xamarin.Forms Při vytvoření LoadFromXaml
třídy XAML je metoda nepřímo volána. K tomu dochází, protože soubor kódu pro třídu XAML volá metodu InitializeComponent
z jeho konstruktoru:
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
Když Visual Studio sestaví projekt obsahující soubor XAML, parsuje soubor XAML a vygeneruje soubor kódu jazyka C# (například MainPage.xaml.g.cs), který obsahuje definici InitializeComponent
metody:
private void InitializeComponent()
{
global::Xamarin.Forms.Xaml.Extensions.LoadFromXaml(this, typeof(MainPage));
...
}
Metoda InitializeComponent
volá metodu LoadFromXaml
pro extrahování souboru XAML (nebo jeho kompilovaného binárního souboru) z knihovny .NET Standard. Po extrakci inicializuje všechny objekty definované v souboru XAML, spojí je všechny v relacích nadřazený-podřízený, připojí obslužné rutiny událostí definované v kódu k událostem nastaveným v souboru XAML a nastaví výsledný strom objektů jako obsah stránky.
Načítání XAML za běhu
Metody LoadFromXaml
jsou public
, a proto lze volat z Xamarin.Forms aplikací pro načtení a parsovat XAML za běhu. To umožňuje scénáře, jako je například stažení XAML z webové služby, vytvoření požadovaného zobrazení z XAML a zobrazení v aplikaci.
Upozorňující
Načítání XAML za běhu má značné náklady na výkon a obecně by se mělo vyhnout.
Následující příklad kódu ukazuje jednoduché použití:
using Xamarin.Forms.Xaml;
...
string navigationButtonXAML = "<Button Text=\"Navigate\" />";
Button navigationButton = new Button().LoadFromXaml(navigationButtonXAML);
...
_stackLayout.Children.Add(navigationButton);
V tomto příkladu Button
se vytvoří instance s hodnotou vlastnosti Text
nastavenou z XAML definovaného v souboru string
. Potom Button
se přidá do objektu StackLayout
definovaného v XAML pro stránku.
Poznámka:
Metody LoadFromXaml
rozšíření umožňují zadat argument obecného typu. Je však zřídka nutné zadat argument typu, protože bude odvozen z typu instance, ve které pracuje.
Tuto LoadFromXaml
metodu lze použít k nafouknutí libovolného XAML, přičemž následující příklad nafoukne ContentPage
a pak na něj přejde:
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);
Přístup k prvkům
Načtení XAML za běhu pomocí LoadFromXaml
metody neumožňuje přístup silného typu k elementům XAML, které mají zadané názvy objektů modulu runtime (pomocí x:Name
). Tyto elementy XAML je však možné načíst pomocí FindByName
metody a pak k němu přistupovat podle potřeby:
// 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";
...
V tomto příkladu je xaml pro akumulační ContentPage
. Tento XAML obsahuje pojmenovaný monkeyName
Label
, který je načten pomocí FindByName
metody, před jeho Text
vlastnost je nastavena.