Поделиться через


Загрузка XAML во время выполнения в Xamarin.Forms

Пространство Xamarin.Forms.Xaml имен включает два LoadFromXaml метода расширения, которые можно использовать для загрузки и анализа XAML во время выполнения.

Общие сведения

Xamarin.Forms При построении LoadFromXaml класса XAML метод вызывается косвенно. Это происходит из-за того, что файл кода для класса XAML вызывает InitializeComponent метод из конструктора:

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

Когда Visual Studio создает проект, содержащий XAML-файл, он анализирует XAML-файл для создания файла кода C# (например, MainPage.xaml.g.cs), содержащего определение InitializeComponent метода:

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

Метод InitializeComponent вызывает LoadFromXaml метод для извлечения XAML-файла (или его скомпилированного двоичного файла) из библиотеки .NET Standard. После извлечения он инициализирует все объекты, определенные в XAML-файле, подключает их все вместе в отношениях родительского дочернего объекта, присоединяет обработчики событий, определенные в коде, к событиям, заданным в XAML-файле, и задает результирующий дерево объектов в качестве содержимого страницы.

Загрузка XAML во время выполнения

Эти LoadFromXaml методы могут вызываться publicиз Xamarin.Forms приложений для загрузки и анализировать XAML во время выполнения. Это позволяет таким сценариям, как приложение скачивать XAML из веб-службы, создавать необходимое представление из XAML и отображать его в приложении.

Предупреждение

Загрузка XAML во время выполнения имеет значительные затраты на производительность и, как правило, следует избегать.

В следующем примере кода показано простое использование:

using Xamarin.Forms.Xaml;
...

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

В этом примере Button создается экземпляр, при Text этом его значение свойства устанавливается из XAML, определенного в файле string. Затем он Button добавляется в код StackLayout XAML для страницы.

Примечание.

Методы LoadFromXaml расширения позволяют указывать аргумент универсального типа. Однако редко необходимо указать аргумент типа, так как он будет выводиться из типа экземпляра, на который он работает.

Этот LoadFromXaml метод можно использовать для раздувания любого XAML с помощью следующего примера ContentPage и последующего перехода к нему:

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

Доступ к элементам

Загрузка XAML во время выполнения с LoadFromXaml помощью метода не разрешает строго типизированный доступ к элементам XAML с указанными именами объектов среды выполнения (с помощью x:Name). Однако эти элементы XAML можно получить с помощью метода, а затем получить к ней FindByName доступ по мере необходимости:

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

В этом примере КОД XAML для a ContentPage раздувается. Этот XAML включает именованный Label monkeyNameобъект, который извлекается с помощью FindByName метода, прежде чем Text его свойство задано.