Начало работы с XAML
В приложении .NET Multi-platform App UI (.NET MAUI) XAML в основном используется для определения визуального содержимого страницы и работает вместе с файлом кода C#. Файл программной части предоставляет поддержку кода для разметки. Вместе эти два файла вносят вклад в новое определение класса, включающее дочерние представления и инициализацию свойств. В XAML-файле классы и свойства ссылаются на XML-элементы и атрибуты, а также устанавливаются связи между разметкой и кодом.
Анатомия XAML-файла
Новое приложение .NET MAUI содержит три ФАЙЛА XAML и связанные с ними файлы кода:
Первое связывание файлов — App.xaml, XAML-файл и App.xaml.cs, файл кода C# , связанный с XAML-файлом . Как App.xaml , так и App.xaml.cs вносят свой вклад в класс с именем App
, производным от Application
. Второе связывание файлов — AppShell.xaml и AppShell.xaml.cs, которые вносят свой вклад в класс с именем AppShell
, производным от Shell. Большинство других классов с XAML-файлами вносят свой вклад в класс, производный от ContentPageи определяющий пользовательский интерфейс страницы. Это верно для файлов MainPage.xaml и MainPage.xaml.cs .
Файл MainPage.xaml имеет следующую структуру:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyMauiApp.MainPage">
...
</ContentPage>
Два объявления пространстваxmlns
имен XML ссылаются на URI microsoft.com. Однако в этих URI нет содержимого, и они в основном работают в качестве идентификаторов версий.
Первое объявление пространства имен XML означает, что теги, определенные в XAML-файле без префикса, ссылаются на классы в .NET MAUI, например ContentPage. Второе объявление пространства имен определяет префикс x
. Это используется для нескольких элементов и атрибутов, встроенных в xaml и поддерживаемых другими реализациями XAML. Однако эти элементы и атрибуты немного отличаются в зависимости от года, внедренного в URI. .NET MAUI поддерживает спецификацию XAML 2009.
В конце первого тега x
префикс используется для атрибута с именем Class
. Так как использование этого x
префикса является практически универсальным для пространства имен XAML, такие атрибуты XAML, как Class
почти всегда называются x:Class
. Атрибут x:Class
задает полное имя класса .NET: MainPage
класс в MyMauiApp
пространстве имен. Это означает, что этот XAML-файл определяет новый класс, именованный MainPage
в MyMauiApp
пространстве имен, наследуемом от ContentPage (тег, в котором x:Class
отображается атрибут).
Атрибут x:Class
может отображаться только в корневом элементе XAML-файла для определения производного класса C#. Это единственный новый класс, определенный в XAML-файле. Все остальные элементы, отображаемые в XAML-файле, просто создаются из существующих классов и инициализированы.
Файл MainPage.xaml.cs выглядит следующим образом:
namespace MyMauiApp;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
Класс MainPage
является производным от ContentPageопределения частичного класса .
При сборке проекта генератор источника создает новый источник C#, содержащий определение InitializeComponent
метода, вызываемого из MainPage
конструктора, и добавляет его в объект компиляции.
Во время выполнения код в MauiProgram
классе загружает приложение и выполняет App
конструктор класса, который создает экземпляр AppShell
. Класс AppShell
создает экземпляр первой страницы отображаемого приложения, т. е MainPage
. Вызывает MainPage
InitializeComponent
конструктор, который инициализирует все объекты, определенные в XAML-файле, подключает их все вместе в отношениях родительского дочернего объекта, присоединяет обработчики событий, определенные в коде, к событиям, заданным в XAML-файле, и задает результирующий дерево объектов в качестве содержимого страницы.
Примечание.
Класс AppShell
использует оболочку .NET MAUI для задания первой страницы отображаемого приложения. Однако оболочка выходит за рамки этого введение в XAML. Дополнительные сведения см. в оболочке .NET MAUI.
Задание содержимого страницы
Должен ContentPage содержать один дочерний элемент, который может быть представлением или макетом с дочерними представлениями. Дочерний элемент ContentPage автоматически задается в качестве значения ContentPage.Content
свойства.
В следующем примере показана ContentPage содержащая :Label
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.HelloXamlPage"
Title="Hello XAML Page">
<Label Text="Hello, XAML!"
VerticalOptions="Center"
HorizontalTextAlignment="Center"
Rotation="-15"
FontSize="18"
FontAttributes="Bold"
TextColor="Blue" />
</ContentPage>
В примере выше связь между классами, свойствами и XML должна быть очевидной. Класс MAUI .NET (например ContentPage , или Label) отображается в XAML-файле в виде XML-элемента. Свойства этого класса, включая Title
ContentPage и семь свойств Label , обычно отображаются как XML-атрибуты.
Для задания значений этих свойств существует множество сочетаний клавиш. Некоторые свойства являются базовыми типами данных. Например, Title
Text
свойства относятся к типу string
и Rotation
относятся к типу double
. Свойство HorizontalTextAlignment
имеет тип TextAlignment, который является перечислением. Для свойства любого типа перечисления необходимо указать имя члена.
Однако для свойств более сложных типов преобразователи используются для анализа XAML. Это классы в .NET MAUI, производные от TypeConverter
. В приведенном выше примере несколько преобразователей MAUI .NET автоматически применяются для преобразования строковых значений в правильный тип:
LayoutOptionsConverter
VerticalOptions
для свойства. Этот преобразователь преобразует имена общедоступных статических полейLayoutOptions
структуры в значения типаLayoutOptions
.ColorTypeConverter
TextColor
для свойства. Этот преобразователь преобразует имена общедоступных статических полей Colors класса или шестнадцатеричных значений RGB с альфа-каналом или без него.
Перемещение по страницам
При запуске приложения MainPage
.NET MAUI обычно отображается. Чтобы увидеть другую страницу, можно задать ее как новую страницу запуска в файле AppShell.xaml или перейти на новую страницу из MainPage
.
Чтобы реализовать навигацию, в конструкторе MainPage.xaml.cs можно создать простую Button и использовать обработчик событий для перехода к HelloXamlPage
:
public MainPage()
{
InitializeComponent();
Button button = new Button
{
Text = "Navigate!",
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
};
button.Clicked += async (sender, args) =>
{
await Navigation.PushAsync(new HelloXamlPage());
};
Content = button;
}
При компиляции и развертывании новой версии этого приложения на экране появится кнопка. Нажатие клавиши переходит к HelloXamlPage
:
Вы можете вернуться к MainPage
использованию панели навигации, которая отображается на каждой платформе.
Примечание.
Альтернативой этой модели навигации является использование оболочки MAUI .NET. Дополнительные сведения см. в обзоре оболочки .NET MAUI.
Взаимодействие XAML и кода
Дочерний элемент большинства ContentPage производных является макетом, например макетом StackLayout или макетом Grid, который может содержать несколько дочерних элементов. В XAML эти связи родительско-дочерних элементов устанавливаются с обычной XML-иерархией:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<StackLayout>
<Slider VerticalOptions="Center" />
<Label Text="A simple Label"
FontSize="18"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Button Text="Click Me!"
HorizontalOptions="Center"
VerticalOptions="Center" />
</StackLayout>
</ContentPage>
Этот XAML-файл синтаксически завершен и создает следующий пользовательский интерфейс:
Однако в то время как вы можете взаимодействовать с Slider ним, Buttonпользовательский интерфейс не обновляется. Должно Slider привести к отображению Label текущего значения и Button должно выполняться что-то.
Slider Отображение значения с помощью можно Label полностью в XAML с привязкой данных. Однако сначала полезно увидеть решение кода. Даже поэтому для обработки щелчка Button определенно требуется код. Это означает, что файл программной части должен XamlPlusCodePage
содержать обработчики для ValueChanged
события Slider события и Clicked
события Button:
namespace XamlSamples
{
public partial class XamlPlusCodePage
{
public XamlPlusCodePage()
{
InitializeComponent();
}
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = args.NewValue.ToString("F3");
}
async void OnButtonClicked(object sender, EventArgs args)
{
Button button = (Button)sender;
await DisplayAlert("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
}
}
}
Обратно в XAML-файл Slider и Button теги должны включать атрибуты для ValueChanged
и Clicked
событий, ссылающихся на эти обработчики:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamlSamples.XamlPlusCodePage"
Title="XAML + Code Page">
<StackLayout>
<Slider VerticalOptions="Center"
ValueChanged="OnSliderValueChanged" />
<Label x:Name="valueLabel"
Text="A simple Label"
FontSize="18"
HorizontalOptions="Center"
VerticalOptions="Center" />
<Button Text="Click Me!"
HorizontalOptions="Center"
VerticalOptions="Center"
Clicked="OnButtonClicked" />
</StackLayout>
</ContentPage>
Обратите внимание, что назначение обработчика событию имеет тот же синтаксис, что и назначение значения свойству. Кроме того, для ValueChanged
обработчика событий, используемого для отображения текущего Slider Label значения, обработчику необходимо ссылаться на этот объект из кода. Label Поэтому требуется имя, указанное атрибутомx:Name
. Префикс x
атрибута x:Name
указывает, что этот атрибут является встроенным в XAML. Имя атрибута x:Name
имеет те же правила, что и имена переменных C#. Например, он должен начинаться с буквы или подчеркивания и содержать не внедренные пробелы.
Теперь ValueChanged
обработчик событий может задать Label для отображения нового Slider значения, которое доступно из аргументов событий:
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = args.NewValue.ToString("F3");
}
Кроме того, обработчик может получить Slider объект, создающий это событие из аргумента sender
, и получить Value
свойство из этого:
void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
{
valueLabel.Text = ((Slider)sender).Value.ToString("F3");
}
Результатом является то, что любая манипуляция Slider с его значением отображается в :Label
В приведенном выше Button примере имитирует ответ на Clicked
событие, отображая оповещение с Text
кнопкой. Поэтому обработчик событий может привести аргумент к аргументу sender
Button , а затем получить доступ к его свойствам:
async void OnButtonClicked(object sender, EventArgs args)
{
Button button = (Button)sender;
await DisplayAlert("Clicked!", "The button labeled '" + button.Text + "' has been clicked", "OK");
}
Метод OnButtonClicked
определяется так async
, как DisplayAlert метод является асинхронным и должен быть предопределен оператором await
, который возвращается после завершения метода. Так как этот метод получает Button событие из аргумента sender
, один и тот же обработчик может использоваться для нескольких кнопок.
Следующие шаги
XAML в основном предназначен для создания экземпляров и инициализации объектов. Но часто свойства должны быть заданы для сложных объектов, которые не могут быть легко представлены как XML-строки, а иногда свойства, определенные одним классом, должны быть заданы в дочернем классе. Для этих двух потребностей требуются основные функции синтаксиса XAML элементов свойств и присоединенных свойств.