Страницы и XAML

Последнее обновление: 13.12.2022

За управление визуальным интерфейсом в приложении Maui отвечает класс, который реализует интерфейс IApplication. В стандартном проекте Maui уже по умолчанию имеется подобная реализация в виде класса App, который определен в файле App.xaml.cs:

namespace HelloApp;

public partial class App : Application
{
	public App()
	{
		InitializeComponent();

		MainPage = new AppShell();
	}
}

Однако сам класс App непосредственно не определяет графический интерфейс - он лишь устанавливается главную страницу с помощью свойства MainPage.

MainPage = new AppShell();

В .NET MAUI графический интерфейс состоит из страниц. Каждая страница представляет собой объект класса Page. Страница занимает все пространство экрана. То есть то, что мы видим на экране мобильного устройства или в окне десктопного приложения - это страница. Приложение может иметь одну или несколько страниц.

В данном случае в качестве главной страницы приложения используется объект класса AppShell. Одним из родительских классов AppShell является класс Page, поэтому AppShell по сути также является страницей. Однако AppShell не простая страница, а фактически представляет собой оболочку, в которую помещаются простые страницы. Смысл AppShell состоит в том, чтобы упростить организацию страниц и различные действия с ними, в частности, навигацию между страницами.

Определение класса AppShell распределено на два файла: AppShell.xaml и AppShell.xaml.cs.

страница AppShell в .NET MAUI в проекте для C#

Непосредственно сам класс AppShell определен в файле AppShell.xaml.cs:

namespace HelloApp
{
    public partial class AppShell : Shell
    {
        public AppShell()
        {
            InitializeComponent();
        }
    }
}

В классе определен только конструктор, который с помощью вызова InitializeComponent() позволяет загрузить определение интерфейса страницы из файла AppShell.xaml.

XAML

Для определения графического интерфейса в .NET MAUI применяется XAML. XAML представляет язык разметки на основе xml для создания объектов декларативным образом (хотя также можно создавать интерфейс в коде C#, либо комбинировать создание интерфейса в коде XAML и C#).

Использование XAML несет некоторые преимущества.

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

Во-вторых, XAML позволяет описать интерфейс более ясным и понятным способом, такой код гораздо проще поддерживать и обновлять.

В целом XAML позволяет организовать весь пользовательский интерфейс в виде набора страниц подобно тому, как это делается в HTML.

Так, обратимся к файлу AppShell.xaml, который определяет интерфейс для страницы AppShell:

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

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

</Shell>

Элементы в XAML и их атрибуты

Файл с разметкой на xaml представляет собой обычный файл xml, и первой строкой идет стандартное определение xml-файла:

<?xml version="1.0" encoding="UTF-8" ?>

Далее здесь определение корневого элемента, в качестве которого здесь выступает Shell. XAML предлагает очень простую и ясную схему определения различных элементов и их свойств. Каждый элемент, как и любой элемент XML, должен иметь открытый и закрытый тег, как в случае с элементом Shell:

<Shell></Shell>

Либо элемент может иметь сокращенню форму с закрывающим слешем в конце, наподобие:

<ShellContent />

Каждый элемент в XAML представляет объект определенного класса C#, а атрибуты элементов соотносятся со свойствами этих классом. Например, элемент Shell фактически будет представлять объект одноименного класса Shell (Shell - базовый класс для класса AppShell), а элемент ShellContent - объект класса ShellContent.

Каждый элемент в xaml можно сопоставить определенному классу в C#, а каждый атрибут элемента - свойству этого класса. Например, в у элемента Shell задан атрибут Shell.FlyoutBehavior:

Shell.FlyoutBehavior="Disabled"

Свойство Shell.FlyoutBehavior настраивает поведение всплывающего сообщения. В качестве значения оно принимает одну из констант перечисления FlyoutBehavior, в данном случае это значение FlyoutBehavior.Disabled.

Хотя в коде xaml атрибуту Shell.FlyoutBehavior передается просто строка "Disabled", но .NET MAUI с помощью конвертеров типов может преобразовать значения атрибутов в нужные типы.

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

В определении корневого элемента Shell подключаются три пространства имен с помощью атрибутов xmlns.

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

Пространство имен xmlns="http://schemas.microsoft.com/dotnet/2021/maui" определяет большинство типов из .NET MAUI, которые применяются для построения графического интерфейса.

Второе пространство имен http://schemas.microsoft.com/winfx/2009/xaml определяет ряд типов XAML и типы CLR. Так как только одно пространство имен может быть базовым, то это пространство используется с префиксом (или проекцируется на префикс) x: xmlns:x. Это значит, что те свойства элементов, которые заключены в этом пространстве имен, будут использоваться с префиксом x - x:Name или x:Class

Третье пространство имен xmlns:local="clr-namespace:HelloApp" позволяет подключить функционал, который определен в текущем проекте (HelloApp). Это пространство используется с префиксом (или проекцируется на префикс) local: xmlns:local. Значение "clr-namespace" указывает на пространство имен CLR внутри сборки, функционал которого надо подключить в XAML. В данном случае это пространство имен HelloApp, которое по умолчанию соответствует названию проекта. И затем в коде xaml с помощью префикса ocal можно будет обращаться к типам, определенным в текущем проекте.

Также в определении корневого элемента Shell идет атрибут x:Class="HelloApp.AppShell, который указывает на класс, представляющий данную страницу. То есть данный элемент Shell будет связан с классом "HelloApp.AppShell. Причем здесь атрибут используется с префиксом x. Это значит, что атрибут Class берется из пространства имен http://schemas.microsoft.com/winfx/2009/xaml, которое проецируется на данный префикс.

ShellContent

Далее внутри Shell определены непосредственно элементы, которые и будут представлять графический интерфейс. В данном случае это один элемент ShellContent:

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

Опять же здесь в декларативной форме определяется объект класса ShellContent, который устанавливает содержимое страницы AppShell

Свойство Title класса ShellContent определяет заголовок страницы, а свойство Route принимает название корневой страницы.

Свойство ContentTemplate, которое устанавливает шаблон содержимого страницы, в качестве значения принимает объект DataTemplate. С помощью записи "{DataTemplate local:MainPage}" мы указываем, что в качестве шаблона данных будет использоваться страница MainPage, которая определена в проекте. Префикс local указывает, что определение класса MainPage будет браться из текущего проекта.

Таким образом, страница AppShell декларативным образом в коде xaml устанавливает заголовок, шаблон страниц и стартовую страницу, в качестве которой выступает класс MainPage.

MainPage

Собственно визуальный интерфейс и связанная с ним логика в проекте .NET MAUI по умолчанию определяется в классе MainPage, который также разбит на два файла: MainPage.xaml и MainPage.xaml.cs

Сам интрейфейс опять же определяется с помощью кода XAML в файле 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="HelloApp.MainPage">

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

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

            <Label
                Text="Welcome to 
.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>

Здесь опять же мы видим ту же самую структуру, что и в случае с файлом AppShell.xaml, только в качестве корневого элемента используется класс ContentPage (базовый класс для MainPage) - страница, которая имеет некоторое содержимое.

В корневом элементе ContentPage также подключаются используемые пространства имен xaml и определяется имя класса с помощью атрибута x:Class.

Внутри ContentPage определяется более сложная структура. Она содержит элемент ScrollView, который определяет прокручиваемую область. Внутри этой области для вертикального расположения элементов применяется класс VerticalStackLayout. Внутри VerticalStackLayout помещаются одно изображение - элемент Image, две текстовых метки - элементы Label и кнопка - элемент Button.

Таким образом, при запуске приложения мы увидим на экране то содержимое, которое определяется файлом MainPage.xaml:

XAML в .NET MAUI и C#

Стоит отметить, что в принципе нам необязательно использовать подобную конструкцию, когда приложение использует страницу AppShell, которая в свою очередь отображает страницу MainPage. Например, мы могли бы изменить файл App.xaml.cs следующим образом:

namespace HelloApp;

public partial class App : Application
{
	public App()
	{
		InitializeComponent();
		MainPage = new MainPage();  //new AppShell();
	}
}

В данном случае в качестве главной страницы приложения напрямую устанавливается класс MainPage. В принципе свойству Page класса Application мы можем передать любой объект класса Page, который призван выполнять роль главной страницы.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850