Загрузка 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
его свойство задано.