XAML (eXtensible Application Markup Language) - язык разметки, используемый для инициализации объектов в технологиях на платформе .NET. Применительно к WPF (а также к Silverlight) данный язык используется прежде всего для создания пользовательского интерфейса декларативным путем. Хотя функциональность XAML только графическими интерфейсами не ограничивается: данный язык также используется в технологиях WCF и WF, где он никак не связан с графическим интерфейсом. То есть его область шире. Применительно к WPF мы будем говорить о нем чаще всего именно как о языке разметки, который позволяет создавать декларативным путем интерфейс, наподобие HTML в веб-программировании. Однако опять же повторюсь, сводить XAML к одному интерфейсу было бы неправильно, и далее на примерах мы это увидим.
XAML - не является обязательной частью приложения, мы вобще можем обходиться без него, создавая все элементы в файле связанного с ним кода на языке C#. Однако использование XAML все-таки несет некоторые преимущества:
Возможность отделить графический интерфейс от логики приложения, благодаря чему над разными частями приложения могут относительно автономно работать разные специалисты: над интерфейсом - дизайнеры, над кодом логики - программисты.
Компактность, понятность, код на XAML относительно легко поддерживать.
При компиляции приложения в Visual Studio код в xaml-файлах также компилируется в бинарное представление кода xaml, которое называется BAML (Binary Application Markup Language). И затем код baml встраивается в финальную сборку приложения - exe или dll-файл.
При создании нового проекта WPF он уже содержит файлы с кодом xaml. Так, создаваемый по умолчанию в проекте файл MainWindow.xaml будет иметь следующую разметку:
<Window x:Class="XamlApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:XamlApp" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> </Grid> </Window>
Если вы совершенно не знакомы с xaml и с xml, то даже этот небольшой минимальный код окна может вызывать затруднения.
Подобно структуре веб-страничке на html, здесь есть некоторая иерархия элементов. Элементов верхнего уровня является Window
,
который представляет собой окно приложения. При создании других окон в приложении нам придется всегда начинать объявление интерфейса
с элемента Window, поскольку это элемент самого верхнего уровня.
Кроме Window существует еще два элемента верхнего уровня:
Page
Application
Элемент Window имеет вложенный пустой элемент Grid
, а также подобно html-элементам ряд атрибутов (Title, Width, Height) - они задают заголовок,
ширину и высоту окна соответственно.
При создании кода на языке C#, чтобы нам были доступны определенные классы, мы подключаем пространства имен с помощью директивы
using
, например, using System.Windows;
.
Чтобы задействовать элементы в XAML, мы также подключаем пространства имен. Вторая и третья строчки как раз и представляют собой пространства имен, подключаемые в проект по умолчанию. А атрибут xmlns представляет специальный атрибут для определения пространства имен в XML.
Так, пространство имен http://schemas.microsoft.com/winfx/2006/xaml/presentation содержит описание и определение большинства элементов управления. Так как является пространством имен по умолчанию, то объявляется без всяких префиксов.
http://schemas.microsoft.com/winfx/2006/xaml - это пространство имен, которое определяет некоторые свойства XAML, например свойство Name или Key.
Используемый префикс x в определении xmlns:x
означает, что те свойства элементов, которые заключены в этом пространстве имен, будут использоваться с префиксом x -
x:Name
или x:Key
. Это же пространство имен используется уже в первой строчке x:Class="XamlApp.MainWindow" - здесь создается новый класс MainWindow и соответствующий ему файл кода,
куда будет прописываться логика для данного окна приложения.
Это два основных пространства имен. Рассмотрим остальные:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008": предоставляет поддержку атрибутов в режиме дизайнера. Это пространство имен преимущественно предназначено для другого инструмента по созданию дизайна на XAML - Microsoft Expression Blend
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006": обеспечивает режим совместимости разметок XAML. В определении объекта Window двумя строчками ниже можно найти его применение:
mc:Ignorable="d"
Это выражение позволяет игнорировать парсерам XAML во время выполнения приложения дизайнерские атрибуты из пространства имен с префиксом d, то есть из "http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:XamlApp": пространство имен текущего проекта. Так как в моем случае проект называется XamlApp, то простраство имен называется аналогично. И через префикс local я смогу получить в XAML различные объекты, которые я определил в проекте.
Важно понимать, что эти пространства имен не эквивалентны тем пространствам имен, которые подключаются при помощи директивы using
в c#.
Так, например, http://schemas.microsoft.com/winfx/2006/xaml/presentation подключает в проект следующие пространства имен:
System.Windows
System.Windows.Automation
System.Windows.Controls
System.Windows.Controls.Primitives
System.Windows.Data
System.Windows.Documents
System.Windows.Forms.Integration
System.Windows.Ink
System.Windows.Input
System.Windows.Media
System.Windows.Media.Animation
System.Windows.Media.Effects
System.Windows.Media.Imaging
System.Windows.Media.Media3D
System.Windows.Media.TextFormatting
System.Windows.Navigation
System.Windows.Shapes
System.Windows.Shell
XAML предлагает очень простую и ясную схему определения различных элементов и их свойств. Каждый элемент, как и любой элемент XML, должен иметь открытый и закрытый тег, как в случае с элементом Window:
<Window></Window>
Либо элемент может иметь сокращенню форму с закрывающим слешем в конце, наподобие:
<Window />
Но в отличие от элементов xml каждый элемент в XAML соответствует определенному классу C#. Например, элемент Button
соответствует классу System.Windows.Controls.Button
. А свойства этого класса соответствуют атрибутам элемента Button.
Например, добавим кнопку в создаваемую по умолчанию разметку окна:
<Window x:Class="XamlApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:XamlApp" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid x:Name="grid1"> <Button x:Name="button1" Width="100" Height="30" Content="Кнопка" /> </Grid> </Window>
Сначала идет элемент самого высшего уровня - Window, затем идет вложенный элемент Grid - контейнер для других элементов, и в нем уже определен элемент Button, представляющий кнопку.
Для кнопки мы можем определить свойства в виде атрибутов. Здесь определены атрибуты
x:Name
(имя кнопки), Width
, Height
и Content
. Причем, атрибут x:Name
берется в данном случае
из пространства имен "http://schemas.microsoft.com/winfx/2006/xaml", которое сопоставляется с префиксом x. А остальные атрибуты
не используют префиксы, поэтому берутся из основного пространства имен "http://schemas.microsoft.com/winfx/2006/xaml/presentation".
Подобным образом мы можем определить и другие атрибуты, которые нам нужны. Либо мы в общем можем не определять атрибуты, и тогда они будут использовать значения по умолчанию.
Определив разметку xaml, мы можем запустить проект, и нам отобразится графически весь код xaml - то есть наша кнопка:
При определении интерфейса в XAML мы можем столкнуться с некоторыми ограничениями. В частости, мы не можем использовать специальные символы,
такие как знак амперсанда &, кавычки " и угловые скобки < и >.
Например, мы хотим, чтобы текст кнопки был следующим: <"Hello">
. У кнопки есть свойство Content
, которое задает содержимое кнопки.
И можно предположить, что нам надо написать так:
<Button Content="<"Hello">" />
Но такой вариант ошибочен и даже не скомпилирутся. В этом случае нам надо использовать специальные коды символов:
Символ | Код |
< | < |
> | > |
& | & |
" | " |
Например:
<Button Content="<"Hello">" />
Еще одна проблема, с которой мы можем столкнуться в XAML - добавление пробелов. Возьмем, к примеру, следующее определение кнопки:
<Button> Hello World </Button>
Здесь свойство Content задается неявно в виде содержимого между тегами <Button>....</Button>
. Но несмотря на то, что
у нас несколько пробелов между словами "Hello" и "World", XAML по умолчанию будет убирать все эти пробелы. И чтобы сохранить пробелы, нам надо использовать
атрибут xml:space="preserve"
:
<Button xml:space="preserve"> Hello World </Button>