Перейти к основному содержимому

XAML

Разработчику Аналитику Тестировщику
Архитектору Инженеру


XAML

Основы XAML

XAML (eXtensible Application Markup Language) — расширяемый язык разметки на базе XML для декларативного описания приложений. Произносят "замл" или "зэмл". Разработан Microsoft; файл хранится с расширением .xaml, MIME-тип — application/xaml+xml.

XAML описывает дерево объектов UI — окно, панели, контролы, стили и привязки данных. Компилятор или загрузчик разметки превращает XML в экземпляры классов UI-фреймворка. Логика приложения остаётся в процедурном коде (C#, VB.NET, F# и др.) в code-behind или во ViewModel при MVVM — XAML отвечает прежде всего за пользовательский интерфейс.

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

XAML читается и человеком, и машиной. Его типичные сценарии:

Логика приложения остаётся в C# (или другом .NET-языке) в файлах code-behind или во ViewModel при паттерне MVVM — разметка отвечает за внешний вид и привязки.

ПлатформаРасширение файлаПространство имён по умолчанию
WPF.xamlhttp://schemas.microsoft.com/winfx/2006/xaml/presentation
WinUI / UWP.xamlзависит от шаблона проекта (WinUI 3)
.NET MAUI.xamlhttp://schemas.microsoft.com/dotnet/2021/maui
Avalonia.axamlhttps://github.com/avaloniaui

Подробнее о выборе desktop-стека: Разработка приложений для Windows, про Avalonia в .NET: UI-фреймворки .NET.


Модель XAML — элементы, Application и разделение кода

Элементы XAML делятся на четыре категории:

  1. Панели компоновки — задают, как располагаются вложенные элементы (Grid, StackPanel, DockPanel и др.; в WPF заявлено семь классов панелей).
  2. Элементы управления — кнопки, поля ввода, списки.
  3. Элементы, связанные с документом — форматированный текст, страницы, навигация.
  4. Графические фигуры — линии, прямоугольники, эллипсы, пути (vector shapes).

Положение элемента задают атрибутами-свойствами (Margin, HorizontalAlignment) — синтаксис ближе к ООП-языкам, чем к CSS, но привычен desktop-разработчикам.

В WPF корень приложения — объект Application: он управляет жизненным циклом, генерирует события для пользовательского кода и объединяет окна в одну программу. Многостраничные сценарии поддерживают Page, Frame и навигацию по журналу; контекстные меню строят через ContextMenu.

Процедурный код размещают в том же файле XAML (редко) или в связанных .xaml.cs / ViewModel — при сборке проекта. Так реализована модель разделения кода и дизайна: дизайнер правит разметку в Blend или Visual Studio, программист — ViewModel и сервисы.

ИнструментОриентация
Visual Studioкод, отладка, XAML-редактор, Hot Reload
Expression Blend (legacy) / дизайнер VSанимация, визуальные состояния, стили без ручного XML
XAMLPadбыстрый просмотр фрагментов разметки

Помимо UI, XAML применяли в Windows Workflow Foundation (WWF) — описание workflow, и в Silverlight (урезанный WPF для браузера; поддержка прекращена). Сейчас основные живые направления — WPF, WinUI 3, .NET MAUI и Avalonia (AXAML).


Синтаксис и структура документа

Структурно XAML похож на XML — элементы, атрибуты, вложенность. Каждый тег обычно соответствует типу из библиотеки UI (например, Button → класс System.Windows.Controls.Button в WPF).

Минимальное окно WPF:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.MainWindow"
Title="Пример XAML" Height="300" Width="400">
<Grid>
<TextBlock Text="Привет, мир!"
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</Window>

Разбор по частям:

  • <Window> — корневой элемент; в MAUI это будет <ContentPage>, в Avalonia — <Window> с другими xmlns.
  • xmlns — URI пространства имён: какие теги "знает" парсер (презентация, системные типы .NET).
  • xmlns:x — служебное пространство XAML — x:Class, x:Name, x:Key и т.д.
  • x:Class — связь разметки с partial-классом в C# (MainWindow.xaml + MainWindow.xaml.cs).
  • Свойства задаются атрибутами (Title="...") или дочерними элементами (см. ниже property element syntax).
  • x:Name (не показан в примере) — имя экземпляра в code-behind; в MVVM чаще используют только привязки без имён в коде.

Property element syntax — когда значение сложное (не строка), его пишут как вложенный тег:

<Button>
<Button.Content>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Сохранить" Margin="0,0,8,0"/>
</StackPanel>
</Button.Content>
</Button>

Markup extensions — фигурные скобки в атрибутах, расширяющие синтаксис: &#123;Binding Path=UserName&#125;, &#123;StaticResource AccentBrush&#125;, &#123;x:Null&#125;. Это инструкции парсеру XAML.

Ресурсы — словарь в Window.Resources или Application.Resources для стилей, кистей, шаблонов:

<Window.Resources>
<SolidColorBrush x:Key="AccentBrush" Color="#0078D4"/>
<Style x:Key="PrimaryButton" TargetType="Button">
<Setter Property="Background" Value="{StaticResource AccentBrush}"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Padding" Value="12,6"/>
</Style>
</Window.Resources>

Привязка данных (data binding) связывает свойство UI с объектом или ViewModel без ручного обновления в коде:

<TextBox Text="{Binding UserName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="{Binding WelcomeMessage}"/>

Режимы OneWay, TwoWay, OneTime; конвертеры — через &#123;Binding ..., Converter=...&#125;. В WPF дополнительно:

МеханизмНазначение
Bindingосновная привязка свойства к источнику данных или другому элементу
MultiBindingнесколько источников; результат через IMultiValueConverter
TemplateBindingвнутри ControlTemplate — связь с свойством контрола, к которому применён шаблон
PriorityBindingсписок привязок по приоритету; используется первая успешная

Пример связи слайдера и поля без code-behind (из документации WPF):

<StackPanel Orientation="Horizontal">
<Slider x:Name="slider" Width="200" Minimum="1" Maximum="100" Value="60"/>
<TextBox Text="{Binding ElementName=slider, Path=Value, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>

В production UI на XAML обычно строят на MVVM (desktop-стеки).

Play ITЗагрузка интерактивного демо…


Популярные элементы разметки

Ниже — типичные теги, которые встречаются в большинстве XAML-проектов (имена свойств в WPF; в MAUI/Avalonia возможны небольшие отличия в пространствах имён и части API).


Контейнеры компоновки

Grid — строки и столбцы, ячейки через Grid.Row / Grid.Column:

<Grid Margin="16">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Имя:" VerticalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="1" Margin="8,0,0,0"/>
<Button Grid.Row="1" Grid.Column="1" Content="OK" HorizontalAlignment="Right" Margin="0,12,0,0"/>
</Grid>

StackPanel — элементы в ряд или столбик:

<StackPanel Orientation="Vertical" Spacing="8">
<TextBlock Text="Заголовок" FontSize="20" FontWeight="Bold"/>
<TextBlock Text="Подзаголовок" Opacity="0.7"/>
<Button Content="Далее"/>
</StackPanel>

(Spacing — в WinUI/MAUI; в классическом WPF отступы задают через Margin.)

DockPanel — пристыковка к краям; WrapPanel — перенос на новую строку; Canvas — абсолютные координаты Canvas.Left / Canvas.Top.


Ввод и действия

<Button Content="Отправить" Click="OnSendClick" IsEnabled="{Binding CanSubmit}"/>
<CheckBox Content="Запомнить меня" IsChecked="{Binding RememberMe, Mode=TwoWay}"/>
<RadioButton GroupName="theme" Content="Тёмная" IsChecked="True"/>
<ComboBox ItemsSource="{Binding Countries}" DisplayMemberPath="Name"
SelectedItem="{Binding SelectedCountry, Mode=TwoWay}"/>
<Slider Minimum="0" Maximum="100" Value="{Binding Volume, Mode=TwoWay}"/>
<ProgressBar Value="{Binding UploadPercent}" Maximum="100" Height="8"/>

Текст и списки

<TextBlock Text="{Binding StatusMessage}" TextWrapping="Wrap"/>
<Label Content="Пароль:" Target="{Binding ElementName=PwdBox}"/>
<PasswordBox x:Name="PwdBox"/>
<TextBox Text="{Binding SearchQuery, Mode=TwoWay}" PlaceholderText="Поиск…"/>

<ListBox ItemsSource="{Binding Items}" SelectedItem="{Binding Current, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" FontWeight="SemiBold"/>
<TextBlock Text="{Binding Subtitle}" Margin="8,0,0,0" Opacity="0.6"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

В MAUI списки чаще через CollectionView; в WPF для больших данных — DataGrid или виртуализированный ListView.


Оформление и медиа

<Border Background="#F3F3F3" CornerRadius="8" Padding="16" BorderBrush="#E0E0E0" BorderThickness="1">
<TextBlock Text="Карточка" />
</Border>

<Image Source="/Assets/logo.png" Width="48" Height="48" Stretch="Uniform"/>
<Separator Margin="0,12"/>
<Menu>
<MenuItem Header="Файл">
<MenuItem Header="Открыть…" InputGestureText="Ctrl+O"/>
<MenuItem Header="Выход"/>
</MenuItem>
</Menu>

UserControl и DataTemplate / ControlTemplate выносят повторяющиеся фрагменты UI в переиспользуемые куски разметки — основа единого дизайна в больших приложениях.


AXAML (Avalonia)

AXAML — то же семейство декларативной XAML-разметки, но в файлах с расширением .axaml в проектах Avalonia UI. Avalonia — кроссплатформенный UI-фреймворк для .NET (Windows, Linux, macOS, экспериментально мобильные и WebAssembly), вдохновлённый WPF: похожие имена контролов, привязки, стили, DataTemplate.

Почему отдельное расширение:

  • инструменты и шаблоны проекта различают свой парсер и набор xmlns;
  • избегают путаницы с WPF .xaml в одном solution;
  • часть WPF-XAML не копируется в Avalonia один в один (другие пространства имён, отсутствие некоторых типов Win32).

Пример окна Avalonia:

<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyApp.Views.MainWindow"
Title="Пример AXAML"
Width="400" Height="300">
<StackPanel Margin="24" Spacing="12">
<TextBlock Text="Привет из Avalonia!" FontSize="24"/>
<TextBox Watermark="Введите email"/>
<Button Content="Войти" HorizontalAlignment="Stretch"/>
</StackPanel>
</Window>

Типичные отличия от WPF при переносе разметки:

ТемаWPFAvalonia (AXAML)
URI презентации.../xaml/presentationhttps://github.com/avaloniaui
Расширение.xaml.axaml
Code-behindMainWindow.xaml.csMainWindow.axaml.cs
Placeholder в поле вводачасто через стильсвойство Watermark у TextBox
РендерингDirectX / WPF pipelineSkia, единый на платформах

Синтаксис привязок, ресурсов, x:Name, x:Class, стилей и шаблонов в AXAML узнаваем тем, кто уже писал WPF — это главный аргумент в пользу Avalonia для кроссплатформенного desktop без смены парадигмы UI.

Документация: Introduction to XAML, Avalonia в энциклопедии .NET.


XAML и обычный XML

XAML наследует правила XML (один корень, закрытие тегов, экранирование &, <). Но это не "конфигурационный XML" вроде appSettings: разметка описывает граф объекта UI, а не произвольные ключи настроек. Отличия:

  • теги соответствуют типам из сборок UI-фреймворка;
  • атрибуты — чаще свойства зависимостей (dependency properties), а не произвольные строки;
  • поддерживаются markup extensions и привязки, которых в чистом XML нет.

Для настроек приложения по-прежнему используют JSON, YAML или XML конфигурации — см. раздел Конфигурации и данные.


Практика и документация

Типичные ошибки новичков — несовпадение x:Class с именем класса в code-behind, опечатка в xmlns, привязка к несуществующему свойству ViewModel, забытый Mode=TwoWay для полей ввода. После правки разметки в Visual Studio помогают XAML Hot Reload (WPF/WinUI/MAUI) и пересборка при изменении x:Class или структуры проекта.

XAML и AXAML — мощный способ отделить внешний вид от логики в современных .NET-приложениях; интерактивный пример выше показывает, как параметры окна и компоновки меняют и разметку, и превью.