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


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

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

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

При построении проекта, содержащего XAML-файл, генератор источника создает новый источник C#, содержащий определение InitializeComponent метода, и добавляет его в объект компиляции. В следующем примере показан созданный InitializeComponent метод для MainPage класса:

private void InitializeComponent()
{
    global::Microsoft.Maui.Controls.Xaml.Extensions.LoadFromXaml(this, typeof(MainPage));
    ...
}

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

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

Класс Extensions в Microsoft.Maui.Controls.Xaml пространстве имен включает LoadFromXaml методы расширения, которые можно использовать для загрузки и анализа XAML во время выполнения. Эти LoadFromXaml методы можно publicвызывать из приложений .NET MAUI для загрузки и анализа XAML во время выполнения. Это позволяет сценариям, таким как приложение скачивать XAML из веб-службы, создавать необходимое представление из XAML и отображать его в приложении.

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

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

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

Загрузка XAML во время выполнения не является безопасной и не должна использоваться с полной обрезкой или NativeAOT. Его можно безопасно обрезать, заключив все типы, которые можно загрузить во время выполнения с DynamicallyAccessedMembers помощью атрибута или атрибута DynamicDependency . Однако это очень подвержено ошибкам и не рекомендуется. Кроме того, загрузка XAML во время выполнения имеет значительные затраты на производительность. Дополнительные сведения см. в разделе об обрезке приложения .NET MAUI и развертывания Собственного AOT.

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

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

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

Примечание.

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

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

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

Элементы Access

Загрузка 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://schemas.microsoft.com/dotnet/2021/maui\"\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 его свойство задано.