Хотя мы можем создавать весь интерфейс и в коде C#, как было рассмотрено в прошлой теме, но более предпочтительным способом является его описание в XAML. XAML представляет язык разметки на основе xml для создания объектов декларативным образом. Собственно поэтому при создании проекта уже по умолчанию в него добавляются два файла MainPage.xaml и MainPage.xaml.cs.
Использование XAML несет некоторые преимущества.
Во-первых, с помощью XAML мы можем отделить графический интерфейс от логики приложения, благодаря чему над разными частями приложения могут относительно автономно работать разные специалисты: над интерфейсом - дизайнеры, над кодом логики - программисты.
Во-вторых, XAML позволяет описать интерфейс более ясным и понятным способом, такой код гораздо проще поддерживать и обновлять.
В целом XAML позволяет организовать весь пользовательский интерфейс в виде набора страниц подобно тому, как это делается в HTML.
Файл MainPage.xaml содержит разметку визуального интерфейса страницы:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloApp.MainPage"> <StackLayout> <Frame BackgroundColor="#2196F3" Padding="24" CornerRadius="0"> <Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36"/> </Frame> <Label Text="Start developing now" FontSize="Title" Padding="30,10,30,10"/> <Label Text="Make changes to your XAML file and save to see your UI update in the running app with XAML Hot Reload. Give it a try!" FontSize="16" Padding="30,0,30,0"/> <Label FontSize="16" Padding="30,24,30,0"> <Label.FormattedText> <FormattedString> <FormattedString.Spans> <Span Text="Learn more at "/> <Span Text="https://aka.ms/xamarin-quickstart" FontAttributes="Bold"/> </FormattedString.Spans> </FormattedString> </Label.FormattedText> </Label> </StackLayout> </ContentPage>
Файл с разметкой на xaml представляет собой обычный файл xml, и первой строкой идет стандартное определение xml-файла.
Далее здесь определен элемент ContentPage
, который представляет страницу и внутри которого определена метка с текстом.
В определении корневого элемента ContentPage подключаются два пространства имен с помощью атрибутов xmlns.
Пространство имен http://xamarin.com/schemas/2014/forms определяет большинство типов из Xamarin Forms, которые применяются для построения графического интерфейса.
Второе пространство имен http://schemas.microsoft.com/winfx/2009/xaml определяет ряд типов XAML и типы CLR. Так как только одно
пространство имен может быть базовым, то это пространство используется с префиксом (или проекцируется на префикс) x: xmlns:x
. Это значит, что те свойства элементов, которые заключены в этом пространстве имен,
будут использоваться с префиксом x - x:Name
или x:Class
После подключения пространств имен идет атрибут x:Class="HelloApp.MainPage
, который указывает на класс, представляющий данную страницу.
Далее внутри ContentPage определены непосредственно элементы, которые и будут представлять графический интерфейс.
В данном случае в ContentPage определен контейнер компоновки StackLayout, который по умолчанию располагает вложенные элементы в столбик. А в элементе StackLayout расположен элементы Frame и Label.
XAML предлагает очень простую и ясную схему определения различных элементов и их свойств. Каждый элемент, как и любой элемент XML, должен иметь открытый и закрытый тег, как в случае с элементом ContentPage:
<Label></Label>
Либо элемент может иметь сокращенню форму с закрывающим слешем в конце, наподобие:
<Label />
Каждый элемент в XAML представляет объект определенного класса C#, а атрибуты элементов соотносятся со свойствами этих классом. Например, элемент ContentPage фактически будет представлять объект одноименного класса ContentPage, а элемент Label - объект класса Label.
Каждый элемент в xaml можно сопоставить определенному классу в C#, а каждый атрибут элемента - свойству этого класса. Однако если свойства классов могут принимать значения различных типов: string, double, int и т.д. То в XAML атрибуты элементов имеют текстовые значения. Например, возьмем один из определенных на странице элементов Label:
<Label Text="Welcome to Xamarin.Forms!" HorizontalTextAlignment="Center" TextColor="White" FontSize="36" />
Свойство Text
класса Label в качестве значение принимает строку, поэтому здесь никаких преобразований не потребуется. Но, к примеру, свойство
HorizontalTextAlignment
, которое устанавливает выравнивание текста по горизонтали, в качестве значения принимает одну из констант перечисления TextAlignment, например,
TextAlignment.Center
. Однако в коде XAML мы присваиваем просто значение Center
. Дело в том, что в Xamarin Forms действуют конвертеры типов, которые позволяют преобразовать
от одного типа к другому.
Кроме простых свойств, которые могут устанавливаться в с помощью простой строки, например, <Label Text="Welcome to Xamarin.Forms!" />
, в XAML могут применяться
сложные или комплексные свойства. В таких случаях свойство класса может принимать в качестве значения какой-нибудь сложный объект, который в свою очередь
имеет некоторый набор свойств. Сложные свойства определяются в формате:
<Элемент.Свойство> <Сложный_объект /> </Элемент.Свойство>
Например, возьмем другой, определенный на странице элемент Label:
<Label FontSize="16" Padding="30,24,30,0"> <Label.FormattedText> <FormattedString> <FormattedString.Spans> <Span Text="Learn more at "/> <Span Text="https://aka.ms/xamarin-quickstart" FontAttributes="Bold"/> </FormattedString.Spans> </FormattedString> </Label.FormattedText> </Label>
Свойство FormattedText представляет форматированный текст (текст со сложным оформлением) и является сложным свойством. В качестве значения оно принимает объект FormattedString, который передается в качестве вложенного объекта:
<FormattedString> <FormattedString.Spans> <Span Text="Learn more at "/> <Span Text="https://aka.ms/xamarin-quickstart" FontAttributes="Bold"/> </FormattedString.Spans> </FormattedString>
У объекта FormattedString, в свою очередь, имеет свойство Spans, которое также является
сложным свойством и которое представляет набор элементов Span - отдельных кусочков текста. А у каждого элемента Span устанавливается атрибут Text
, который задает выводимый текст.