Краткое руководство: создание пользовательского интерфейса с помощью XAML (XAML)

Applies to Windows and Windows Phone

Если приложение разрабатывается на Microsoft Visual Basic, C# или с помощью расширений компонентов Visual C++ (C++/CX), то пользовательский интерфейс определяется на языке XAML. XAML — это декларативный язык, который используется для создания пользовательского интерфейса приложения: элементов управления, фигур, текста и другого содержимого, отображаемого на экране. Если вы знакомы с веб-программированием, то XAML покажется вам похожим на HTML. Как и HTML, язык XAML состоит из элементов и атрибутов, но XAML основан на XML и должен следовать правилам XML, включая правильную организацию. Вы можете спросить: зачем изучать XAML, если интерфейс можно создать в Microsoft Visual Studio или в Blend для Visual Studio? Разметку можно создавать в различных средствах, но чтобы понять или настроить пользовательский интерфейс, вам неизбежно придется работать с XAML. Кроме того, если требуется тонкая настройка или просто нужно разобраться, как работает приложение, иногда проще написать код интерфейса вручную.

Схема: как эта тема связана с другими? См. разделы:

Предварительные требования

Предполагается, что вы умеете создавать простые приложения среды выполнения Windows на Visual Basic, C# или C++. Инструкции по созданию первого приложения среды выполнения Windows см. в разделе Создание первого приложения Магазина Windows на C#, C++ или Visual Basic.

Пример на языке XAML

Вот простой пример XAML-кода, который создает кнопку.


<Grid Margin="12,0,12,0">
    <Button Content="Click Me"/>
</Grid>

Воспользуйтесь элементом <Button>, чтобы определить элемент управления Button. По возможности настройте динамическое определение размеров кнопки либо при необходимости укажите точный размер, используя атрибуты Width и Height. Элемент <Grid> создается, когда в Visual Studio создается новое приложение среды выполнения Windows на C++, C# или Visual Basic, и используется для задания расположения объектов. Подробнее о макете XAML: Краткое руководство: определение макетов.

Создавать XAML-код можно в Visual Studio. Например, можно перетащить кнопку с панели элементов на поверхность разработки или дважды нажать кнопку на панели элементов.

Интерфейс панели элементов

Visual Studio создает следующий XAML-код.


<Grid>
    <Button Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>

Visual Studio добавляет дополнительные атрибуты, такие как HorizontalAlignment и иногда Margin, чтобы задать расположение кнопки. Возможно, вам не понадобится дополнительная разметка, если ваши требования очень конкретны или если вы планируете позже внести некоторые изменения. В таком случае просто удалите атрибут.

Одним из свойств декларативного языка наподобие XAML является четкое отделение разметки, образующей интерфейс, и кода, который обеспечивает работу приложения. Например, дизайнер в группе разработки может создать пользовательский интерфейс, а затем передать XAML-код разработчику, который добавит процедурный код. Даже если дизайнер и разработчик — одно и то же лицо (как часто бывает), визуальные элементы можно размещать в XAML-файлах (.xaml), а процедурный код пользовательского интерфейса — в файлах кода программной части (.cs и .vb).

XAML — это процедурный код, только проще

Элементы XAML, например <Button />, эквивалентны созданию экземпляров объектов в процедурном коде. Например, рассмотрим следующий XAML-код.


<Grid x:Name="ContentPanel" Margin="12,0,12,0">
    <Button Height="72" Width="160" Content="Click Me" />
</Grid>

В следующем примере показано, каким образом можно заменить часть данного XAML-кода кодом, написанным на C# или Visual Basic.


// Initialize the button
Button myButton = new Button();
// Set its properties
myButton.Width = 160;
myButton.Height = 72;
myButton.Content = "Click Me";
// Attach it to the visual tree, specifically as a child of
// a Grid object (named 'ContentPanel') that already exists. In other words, position
// the button in the UI.
ContentPanel.Children.Add(myButton);

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

Свойства

Есть два способа определить значения свойств на языке XAML.

  • Синтаксис атрибутов
  • Синтаксис свойств

Синтаксис атрибутов имеет структуру attribute="value", которая показана в предыдущих примерах и может быть знакома вам по языку HTML. В следующем примере создается красный объект Rectangle. Зададим в качестве атрибута Fill предопределенное имя цвета, которое синтаксический анализатор XAML преобразует в элемент SolidColorBrush, подходящий для свойства Fill.


<Rectangle Fill="Red" />

Значение цвета также можно указать в синтаксисе свойств.


<Rectangle>
    <Rectangle.Fill>
        <SolidColorBrush Color="Red"/>
    </Rectangle.Fill>
</Rectangle>

В данном случае вместо строки "Red" явно задается объект SolidColorBrush, имеющий тип, который требуется для свойства Fill. По этому примеру может показаться, что синтаксис элемента свойства — это просто трудоемкий способ сделать то же самое. Но дело в том, что не все значения свойств можно указать с помощью простой строки атрибутов. Не все типы можно преобразовать из строк. Кроме того, если нужно указать несколько свойств объекта в качестве значения одного свойства, то, скорее всего, понадобится синтаксис элемента свойства. В следующем примере создается Rectangle, но вместо простой заливки красным применяется градиент, созданный LinearGradientBrush.


<!-- This rectangle is painted with a diagonal linear gradient. -->
<Rectangle Width="200" Height="200">
    <Rectangle.Fill>
        <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
            <GradientStop Color="Yellow" Offset="0.0" />
            <GradientStop Color="Red" Offset="0.25" />
            <GradientStop Color="Blue" Offset="0.75" />
            <GradientStop Color="LimeGreen" Offset="1.0" />
        </LinearGradientBrush> 
    </Rectangle.Fill>
</Rectangle>

Многоцветный градиент

В свойстве Fill для создания градиента используется составной объект LinearGradientBrush. В таких случаях не удается просто указать значение в виде строки, присваиваемой атрибуту, и необходимо использовать синтаксис свойств.

XAML и визуальное дерево

Некоторые элементы XAML, например <Button> и <Grid>, могут содержать другие (дочерние) элементы (узлы). Связь "родители — потомки" задает расположение объектов на экране, их отклик на события, создаваемые пользователем, и другие характеристики. Рассмотрим пример.


<Grid x:Name="ContentPanel" Background="Red" Grid.Row="1" Margin="12,0,12,0">
    <StackPanel Margin="20" Background="Blue">
        <TextBlock x:Name="firstTextBlock" FontSize="30">First TextBlock</TextBlock>
        <TextBlock x:Name="secondTextBlock" FontSize="30">Second TextBlock</TextBlock>
        <TextBlock x:Name="thirdTextBlock" FontSize="30">Third TextBlock</TextBlock>
    </StackPanel>
</Grid>

Синий элемент StackPanel содержится внутри красного элемента Grid. Элементы TextBlock содержатся внутри StackPanel (эти элементы TextBlock являются дочерними для StackPanel). Кроме того, элементы TextBlock располагаются друг над другом в порядке своего объявления в XAML-коде.

Следующая древовидная схема демонстрирует связи между элементами.

Древовидная иерархия элементов

Визуальное дерево не только определяет представление содержимого, но также может влиять на обработку событий. Многие события, связанные с пользовательским интерфейсом и вводом данных, передаются вверх по дереву. Например, можно подключить к элементу StackPanel обработчик событий, которые создаются, когда пользователь нажимает или щелкает любой из объектов TextBlock. Ниже показано, как добавить обработчик события PointerPressed с именем "commonHandler" к StackPanel из схемы.


<Grid Background="Red" x:Name="ContentPanel" Margin="12,0,12,0">
    <StackPanel Margin="20" Background="Blue" PointerPressed="commonHandler">
        <TextBlock x:Name="firstTextBlock" FontSize="30" >First TextBlock</TextBlock>
        <TextBlock x:Name="secondTextBlock" FontSize="30" >Second TextBlock</TextBlock>
        <TextBlock x:Name="thirdTextBlock" FontSize="30" >Third TextBlock</TextBlock>
    </StackPanel>
</Grid>

Обработка события выполняется следующим процедурным кодом.


private void commonHandler(object sender, PointerRoutedEventArgs e)
{
FrameworkElement feSource = e.OriginalSource as FrameworkElement;
switch (feSource.Name)
{
    case "firstTextBlock":
        firstTextBlock.Text = firstTextBlock.Text + " Click!";
        break;
    case "secondTextBlock":
        secondTextBlock.Text = secondTextBlock.Text + " Click!";
        break;
    case "thirdTextBlock":
        thirdTextBlock.Text = thirdTextBlock.Text + " Click!";
        break;
    }
}

Если запустить этот пример и щелкнуть объект TextBlock, то событие регистрируется элементом TextBlock, но затем передается в родительский элемент StackPanel, который обрабатывает событие.

Здесь показано, как событие передается вверх по дереву.

Визуальная древовидная схема, демонстрирующая передачу события вверх по дереву

Поскольку событие продолжает передвижение вверх по дереву, можно перехватывать событие PointerPressed и в элементе Grid.

Подробнее о перенаправленных событиях и написании обработчиков см. в разделе Общие сведения о событиях и перенаправленных событиях.

Краткое руководство по атрибутам XAML и расширениям разметки

Когда XAML-код, созданный в средствах разработки Visual Studio, дорабатывается или изучается в редакторе, часто используются средства разметки, которые уникальны для XAML и непосредственно не присутствуют в базовом языке программирования. Вот некоторые из таких элементов.

  • Атрибут x:Name. Этот атрибут добавляется в любой элемент объекта XAML, где нужно сослаться на созданный экземпляр среды выполнения как часть логики кода программной части. Строка, указанная в атрибуте x:Name, становится именем созданного экземпляра, видимым из разделяемых классов, соответствующих XAML-коду. На экземпляр можно ссылаться по этому имени. Visual Studio и Blend для Visual Studio часто автоматически добавляют в XAML-код атрибут x:Name.
  • Атрибут x:Key. Этот атрибут добавляется в элементы объектов XAML в особом случае: когда определяются ресурсы, содержащиеся в элементе XAML ResourceDictionary. Дополнительные сведения см. в разделе ResourceDictionary и ссылки на ресурсы XAML.
  • Префикс x: в обоих атрибутах x:Key и x:Name указывает, что эти объекты определены пространством имен XAML для самого языка XAML. В результате эти атрибуты можно применять практически к любым элементам XAML, в том числе к тем, которые представляют классы, определенные вами.
  • {Binding} — это расширение разметки XAML, которое используется для привязки данных в XAML. Подробнее о концепциях привязки данных см. в разделе Краткое руководство: привязка данных к элементам управления или Обзор привязки данных.
  • {TemplateBinding} — это специализированный вид объявления привязки, которая соединяет свойства шаблона со свойствами времени выполнения для класса, применяющего этот шаблон. RelativeSource — это связанное расширение привязки, которое может задать свойство привязки {RelativeSource} в разметке.
  • {StaticResource} — это расширение привязки, которое позволяет элементу XAML ResourceDictionary ссылаться на любые ресурсы, определенные в XAML. {StaticResource} принимает единственный аргумент. В нем задается строка ключа, совпадающая с атрибутом x:Key, по которому ресурс определялся в ResourceDictionary.
  • Если в XAML-коде потребуется задать значение null, используйте строку {x:Null}.

Более подробные данные см. в документах Руководство по основам синтаксиса языка XAML, Возможности пространства имен языка XAML (x:) или Расширения пространств имен среды выполнения Windows для XAML.

Связанные разделы

Схема создания приложений среды выполнения Windows на C# или Visual Basic
ResourceDictionary и ссылки на ресурсы XAML
Обзор языка XAML
Руководство по основам синтаксиса языка XAML

 

 

Показ:
© 2014 Microsoft