Введение в XAML

Когда речь идёт про возможности языка C# или, например, про разработку приложений ASP.NET Core Web API, то всё, что нам необходимо для просмотра результатов работы приложения — консоль. В свою очередь, что касается .NET MAUI, то этот фреймворк всё же, в первую очередь, рассчитан на создание красивых приложение с графическим интерфейсом. Поэтому и мы начнем наше изучение .NET MAUI именно с построения графического интерфейса и основ декларативного языка XAML.

XAML

XAML (eXtensible Application Markup Language) — расширяемый язык разметки для приложений, основанный на XML. Язык разработан Microsoft для декларативного программирования приложений. На текущий момент XAML является фактически центральным звеном для таких технологий и платформ как WPF, UWP и, конечно же, .NET MAUI.

Несмотря на то, что XAML основан на XML, этот язык разметки принципиально отличается как от самого XML, так и от того же HTML, как минимум, тем, что XAML с помощью применяемых в нем объектов «привязан» к типам платформы .NET.

Одним из преимуществ использования XAML в проектах является то, что благодаря тому, что интерфейс приложения разрабатывается на XAML, а логика — на C#, появляется возможность разделить проект на две большие части:

  • всё, что связано с графическим интерфейсом разрабатывается дизайнером.
  • вся логика работы приложения ложится на плечи разработчика.

С одной стороны, это действительно так — мы имеем такую возможность. И выглядит это довольно заманчиво, на первый взгляд. Однако, не так уж и часто мы можем встретить внутри небольшой команды разработчиков отдельную штатную единицу профессионального дизайнера, который не только владеет инструментами для создания графики, но и знает язык XAML, а значит и владеет информацией о том, что из себя представляют типы данных .NET, как использовать события C# и т.д.. Поэтому, так или иначе, но разработчику проекта необходимо знать не только C#, но и прекрасно разбираться в том, как наиболее эффективно использовать возможности XAML.

Структура XAML-документа

Вернемся к нашему первому приложению .NET MAUI из предыдущей части. В этом приложении уже содержится три файла XAML с которым мы уже знакомы в самых общих чертах:

Для начала, откроем в редакторе файл App.xaml и посмотрим на его структуру:

<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:FirstApp"
             x:Class="FirstApp.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Resources/Styles/Colors.xaml" />
                <ResourceDictionary Source="Resources/Styles/Styles.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

На первый взгляд, этот документ ничем не отличается от обычного XML-документа — здесь также прослеживается некоторая структура. Корневой элемент Application содержит вложенные элементы, а также пространства имен и атрибут x:Class.  Аналогичным образом, но с другими корневыми элементами, выглядят и два других файла.

Так, AppShell.xaml содержит в качестве корневого элемента Shell:

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    x:Class="FirstApp.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:FirstApp"
    Shell.FlyoutBehavior="Flyout"
    Title="FirstApp">

    <ShellContent
        Title="Home"
        ContentTemplate="{DataTemplate local:MainPage}"
        Route="MainPage" />

</Shell>

Забегая немного вперед, отмечу, что Shell представляет собой страницу-оболочку, которая призвана упростить создание графического интерфейса приложения. Как минимум, благодаря использованию Shell мы получаем уже готовое к использованию боковое меню приложения.

В свою очередь MainPage.xaml представляет собой страницу с неким содержимым:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FirstApp.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Padding="30,0"
            Spacing="25">
            <Image
                Source="dotnet_bot.png"
                HeightRequest="185"
                Aspect="AspectFit"
                SemanticProperties.Description="dot net bot in a hovercraft number nine" />

            <Label
                Text="Hello, World!"
                Style="{StaticResource Headline}"
                SemanticProperties.HeadingLevel="Level1" />

            <Label
                Text="Welcome to &#10;.NET Multi-platform App UI"
                Style="{StaticResource SubHeadline}"
                SemanticProperties.HeadingLevel="Level2"
                SemanticProperties.Description="Welcome to dot net Multi platform App U I" />

            <Button
                x:Name="CounterBtn"
                Text="Click me" 
                SemanticProperties.Hint="Counts the number of times you click"
                Clicked="OnCounterClicked"
                HorizontalOptions="Fill" />
        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

Здесь уже в качестве корневого элемента выступает ContentPage. Даже, если вы мало знакомы с XML, а XAML для нас пока ещё новый язык программирования, зная основные элементы управления, используемые, например, в том же ныне устаревшем .NET Framework, нетрудно догадаться, что на странице MainPage.xaml расположена картинка (элемент Image), текстовая метка (Label) и кнопка (Button). Эти элементы мы можем использовать в XAML-разметке благодаря пространствам имен.

Пространства имен XAML

Подобно XML, в XAML определяются пространства имен — специальные атрибуты корневого элемента документа, имена которых начинаются со строки xmlns. Пространства имен в XAML играют практически ту же роль, что и пространства имен, подключаемые в файлах C#. Благодаря подключенным тем или иным пространствам имен в документа XAML мы получаем возможность использовать объекты .NET. Так, например, посмотрим ещё раз на файл App.xaml. Здесь подключаются три пространства имен:

xmlns="http://schemas.microsoft.com/dotnet/2021/maui" 
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
xmlns:local="clr-namespace:FirstApp"

Первое пространство имен http://schemas.microsoft.com/dotnet/2021/maui содержит основные элементы для построения графического интерфейса приложения .NET MAUI. Например, те самые кнопки, метки, элементы для вывода картинок и так далее.

Пространство имен http://schemas.microsoft.com/winfx/2009/xaml определяется с помощью атрибута xmlns:x. Здесь содержатся такие важные для использования XAML элементы как Name, Key, Class и так далее. Это пространство имен объявляется с префиксом x, что означает то, что все элементы из этого пространства имен должны начинаться с этого же префикса — x. Так, например, чтобы использовать в разметке элемент x:Class="FirstApp.App" здесь же после пространств имен используется с этим префиксом.

И, наконец, третье пространство имен clr-namespace:FirstApp. Здесь используется префикс local. В принципе, префиксы, обычно, выбираются разработчиком достаточно произвольно. Здесь более важным является префикс в имени пространства — clr-namespace: который указывает на то, что подключается пространство имен CLR с именем FirstApp то есть пространство имен C#, используемое по умолчанию в нашем проекте. Благодаря этому пространству имен мы можем в разметке XAML ссылаться на типы, определяемые в C#-коде нашего приложения. Также, используя пространства имен XAML мы можем подключать в проект пространства имен из других сборок. Например, вот такая запись:

xmlns:controls="clr-namespace:Controls;assembly=MyControlLibrary"

означает, что подключается пространство имен Controls из сборки MyControlLibrary.

Code-behind в XAML

Как можно видеть по представленному выше коду, в разметке XAML отсутствует какая-либо логика приложения — здесь содержится только описание интерфейса приложения и подключаются некие файлы ресурсов. Однако, XAML может содержать логику в виде так называемого code-behind и для этого используются частичные (разделяемые) классы C#. Обратите внимание на то, что с каждым XAML-файлом связан файл с именем, соответсвующим следующему шаблону [имя_файла_xaml].xaml.cs.

В этих файлах и может содержаться логика приложения. Например, вернемся к нашему файлу App.xaml. Откроем также в редакторе кода связанный с этим файлом App.xaml.cs.

namespace FirstApp
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
        }

        protected override Window CreateWindow(IActivationState? activationState)
        {
            return new Window(new AppShell());
        }
    }
}

и попробуем сопоставить разметку XAML с кодом C#:

Обратите внимание на то, что имя класса, определенного в XAML в атрибуте x:Class полностью соответствует имени класса, определенного в файле App.xaml.cs. Так,мы «связываем» класс C# с разметкой XAML. Точно таким же образом связываются классы C# с другими XAML-документами, например класс MainPage и MainPage.xaml. Благодаря такому подходу, мы можем ссылаться в XAML на поля и методы частичного класса. Эта возможность продемонстрирована как раз в MainPage.xaml. Обратите внимание на описание кнопки:

<Button
    x:Name="CounterBtn"
    Text="Click me" 
    SemanticProperties.Hint="Counts the number of times you click"
    Clicked="OnCounterClicked"
    HorizontalOptions="Fill" />

Здесь x:Name — атрибут, действие которого подобно тому как мы объявляем переменную в коде C#. То есть здесь, используя привычные нам термины C#, мы объявляем переменную с именем CounterBtn и типом Button. Префикс x у атрибута говорит нам о том, что здесь мы задействовали пространство имен http://schemas.microsoft.com/winfx/2009/xaml.

Далее здесь же мы используем атрибут Clicked, который представляет собой событие — клик по кнопке. В качестве значения для этого атрибута выступает имя метода OnCounterClicked, который содержится в классе MainPage (см. файл MainPage.xaml.cs):

namespace FirstApp
{
    public partial class MainPage : ContentPage
    {
        int count = 0;

        public MainPage()
        {
            InitializeComponent();
        }

        private void OnCounterClicked(object sender, EventArgs e)
        {
            count++;
            if (count == 1)
                CounterBtn.Text = $"Clicked {count} time";
            else
                CounterBtn.Text = $"Clicked {count} times";
            SemanticScreenReader.Announce(CounterBtn.Text);
        }
    }
}

Обратите внимание на то, как мы можем ссылаться на объекты и методы C# в XAML (используя атрибут x:Class в корневом элементе документа) и, наоборот — получать объект из разметки XAML (мы добавляем к элементу разметки атрибут x:Name, чтобы сослаться на этот элемент в коде C#).

Итого

Итак, здесь мы рассмотрели самые основные моменты касающиеся языка XAML — из чего состоит документ XAML, для чего используются пространства имен и то, как мы можем связать разметку XAML м кодом C#. На этом наше изучение возможностей XAML не заканчивается и в следующих частях мы будем рассматривать возможности XAML более подробно.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии