Начало работы с XAML

Browse sample. Обзор примера

В приложении .NET Multi-platform App UI (.NET MAUI) XAML в основном используется для определения визуального содержимого страницы и работает вместе с файлом кода C#. Файл программной части предоставляет поддержку кода для разметки. Вместе эти два файла вносят вклад в новое определение класса, включающее дочерние представления и инициализацию свойств. В XAML-файле классы и свойства ссылаются на XML-элементы и атрибуты, а также устанавливаются связи между разметкой и кодом.

Анатомия XAML-файла

Новое приложение .NET MAUI содержит три ФАЙЛА XAML и связанные с ними файлы кода:

Screenshot of the structure of a new .NET MAUI app.

Первое связывание файлов — 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. Вызывает MainPageInitializeComponentконструктор, который инициализирует все объекты, определенные в 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-элемента. Свойства этого класса, включая TitleContentPage и семь свойств Label , обычно отображаются как XML-атрибуты.

Для задания значений этих свойств существует множество сочетаний клавиш. Некоторые свойства являются базовыми типами данных. Например, TitleText свойства относятся к типу stringи Rotation относятся к типу double. Свойство HorizontalTextAlignment имеет тип TextAlignment, который является перечислением. Для свойства любого типа перечисления необходимо указать имя члена.

Однако для свойств более сложных типов преобразователи используются для анализа XAML. Это классы в .NET MAUI, производные от TypeConverter. В приведенном выше примере несколько преобразователей MAUI .NET автоматически применяются для преобразования строковых значений в правильный тип:

  • LayoutOptionsConverterVerticalOptions для свойства. Этот преобразователь преобразует имена общедоступных статических полей LayoutOptions структуры в значения типа LayoutOptions.
  • ColorTypeConverterTextColor для свойства. Этот преобразователь преобразует имена общедоступных статических полей 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:

Screenshot of rotated Label text.

Вы можете вернуться к 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-файл синтаксически завершен и создает следующий пользовательский интерфейс:

Screenshot of multiple controls on a page.

Однако в то время как вы можете взаимодействовать с 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 обработчика событий, используемого для отображения текущего SliderLabel значения, обработчику необходимо ссылаться на этот объект из кода. 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

Screenshot of multiple controls on a page, with Slider value displayed.

В приведенном выше Button примере имитирует ответ на Clicked событие, отображая оповещение с Text кнопкой. Поэтому обработчик событий может привести аргумент к аргументу senderButton , а затем получить доступ к его свойствам:

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 элементов свойств и присоединенных свойств.