Silverlight: размещение элементов
В первой главе мы рассмотрели базовые приемы программирования. Пойдем копать глубже и узнаем, как размещать элементы в Silverlight-приложениях.
Размещение элементов на форме в Windows Forms было простым занятием. Мы просто перетаскивали нужный элемент с панели инструментов на форму и задавали ему нужные свойства. В приложениях, основанных на XAML, используется другой подход. Важно разобраться с основными принципами размещения элементов в XAML, так как это является основой для дальнейшего успешного программирования на Silverlight (и WPF).
Принципы разметки
Silverlight использует гибкую систему для размещения видимых элементов управления на поверхности. Разметка в коде поддерживает два стиля размещения: динамический и абсолютный. Основными элементами, которые помогают размещать элементы являются:
- Canvas
- StackPanel
- Grid
Рассмотрим каждый из этих элементов, чтобы получить о них более полное представление. Для демонстрации воспользуемся привычными нам кнопками, которые будет размещать на поверхности нашего приложения. Вы можете заново создать новый проект или продолжить работу над предыдущим примером. Будем вносить изменения в коде файла Home.xaml.
Canvas
Элемент Canvas является одним из базовых элементов разметки и позволяет размещать элементы привычным нам способом при помощи задания нужных координат (именно такой способ мы использовали в Windows Forms. Например, попробуем разместить три кнопки следующим образом:
<Canvas> <Button Canvas.Top="50" Canvas.Left="50" Content="Button 1" FontSize="18" Width="150" Height="45" /> <Button Canvas.Top="150" Canvas.Left="20" Content="Button 2" FontSize="18" Width="150" Height="45" /> <Button Canvas.Top="70" Canvas.Left="80" Canvas.ZIndex="99" Content="Button 3" FontSize="18" Width="150" Height="45" /> </Canvas>
На экране мы увидим следующую картинку:

Как вы видите, мы просто задаем координаты для кнопок. В случае необходимости мы также можем указать порядок ZIndex, если одна кнопка перекрывает другую. Подобная модель размещения элементов вполне годится при создании игр или демонстрации каких-то физических процессов. Также Canvas подойдет в тех случаях, когда элементы статичны и хорошо смотрятся в различных ситуациях. Но, на самом деле, существуют более удобные контейнеры, которые вытесняют Canvas, и избавляют программиста от множества проблем, возникаемых при разработке удобных приложений. К числу таких элементов относятся StackPanel или Grid.
StackPanel
StackPanel - элемент-контейнер, который размещает элементы в ряд по вертикали или горизонтали (по умолчанию используется вертикальное размещение). Вот как можно расположить три кнопки по вертикали:
<StackPanel> <Button Margin="10" Content="Button 1" FontSize="18" Width="150" Height="45" /> <Button Margin="10" Content="Button 2" FontSize="18" Width="150" Height="45" /> <Button Margin="10" Content="Button 3" FontSize="18" Width="150" Height="45" /> </StackPanel>

Веб-разработчик может увидеть здесь некоторое сходство с блоковыми элементами HTML (например, DIV), которые размещаются с новой строки. Если вы хотите разместить кнопки по вертикали, то достаточно присвоить атрибуту Orientation элемента StackPanel значение Horizontal:
<StackPanel Orientation="Horizontal"> <Button Margin="10" Content="Button 1" FontSize="18" Width="150" Height="45" /> <Button Margin="10" Content="Button 2" FontSize="18" Width="150" Height="45" /> <Button Margin="10" Content="Button 3" FontSize="18" Width="150" Height="45" /> </StackPanel>

StackPanel позволяет легко управлять расположением элементов друг за другом не думая о вычислениях координат, так как все будет сделано автоматически.
Grid
Grid (сетка) используется очень часто. Возвращаясь к сравнению с элементами HTML, можно сказать, что данный контейнер похож на элемент TABLE (таблица), так как тоже использует столбцы и ряды. Небольшое отличие состоит в том, что в XAML мы сначала задаем структуру для Grid, а уже потом начинаем описывать элементы, которые будут находиться в сетке. Очень удобно, что у Grid есть атрибут ShowGridLines, который показывает линии сетки, что позволит нам наглядно увидеть пример с расположением кнопок (в реальных примерах вы можете не выводить сетку).
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="60" />
<RowDefinition Height="60" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="175" />
<ColumnDefinition Width="175" />
<ColumnDefinition Width="175" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Grid.Row="0" Content="Button 1" FontSize="18" Width="150" Height="45" />
<Button Grid.Column="2" Grid.Row="0" Margin="10" Content="Button 2" FontSize="18" Width="150" Height="45" />
<Button Grid.Column="1" Grid.Row="2" Margin="10" Content="Button 3" FontSize="18" Width="150" Height="45" />
</Grid>
Если внимательно изучить код, то видим, что мы определили три колонки и три ряда и указали их размеры. Далее мы размещаем кнопки, указывая их положение при помощи Grid.Column и Grid.Row:

В Expression Blend размещать элементы удобнее, так как в нем реализован удобный редактор размещения. Поэтому вам стоит изучить данную программу и использовать ее в своих разработках.

Создаем наше Twitter-приложение
Теперь мы вполне можем приступить к разработке настоящего приложения. Now we can start building out our application. Вот как выглядит наше будущее приложение в эскизе:

Основными элементами приложения являются строка для поиска, кнопки и поля для вывода результатов поиска. Также у нас будут задействованы элементы навигации в виде ссылок, с помощью которых мы можем просматривать историю запросов и статистику.
Мы поступили дальновидно, выбрав шаблон с навигацией. Внесем некоторые изменения в файле MainPage.xaml. Около строки 29 удалим логотип приложения (<ContentControl Style="{StaticResource LogoIcon}"/>) , а также изменим текст для ApplicationnameTextBlock на Twitter Search Monitor.
Оставим на минутку наш проект и займемся его структурой. В окне Solution Explorer найдите папку Views, и при помощи контекстного меню создайте новую страницу под именем Search.xaml. Для этого щелкните правой кнопкой на папке Views, далее выберите команды Add | New Item... и в следующем диалоговом окне выберите шаблон Silverlight Page:

У нас появится пустая XAML-страница с сеточной разметкой Grid (по умолчанию). На этой странице мы создадим окно поиска, эскиз которого был показан выше.
Навигация
Изучим основны особенности навигации, используемой в нашем шаблоне. Мы видим, что шаблон состоит из файла MainPage.xaml и дополнительных элементов Home, About. Навигация состоит из трех важных состаляющих: UriMapper, Frame и Page.
UriMapper
В двух словах сложно объяснить, что такое UriMapper. Считайте, что это удобный способ сокращения ссылок. Например, вместо использования строки /Views/Home.xaml, вы можете настроить приложение таким образом, что ссылка будет выглядеть как /Home. Разработчики PHP могут найти тут сходство с настройкой файла .htaccess. Пока этого объяснения будет достаточно. UriMapper является частью элемента Frame в MainPage.xaml:
<navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"
Source="/Home" Navigated="ContentFrame_Navigated"
NavigationFailed="ContentFrame_NavigationFailed">
<navigation:Frame.UriMapper>
<uriMapper:UriMapper>
<uriMapper:UriMapping Uri="" MappedUri="/Views/Home.xaml"/>
<uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
</uriMapper:UriMapper>
</navigation:Frame.UriMapper>
</navigation:Frame>
Frame
Frame - это область для навигации. Вы сначала настраиваете эту область по умолчанию, а затем она меняется при навигации. Если посмотреть на код, приведенный выше, то увидите, что значением атрибута Source для элемента Frame является /Home.
Page
И, наконец, последний важный элемент навигации - это элемент Page, который мы создали сами. Данный элемент является контейнером для содержимого, который выводится в Frame. Можете рассматривать его как элемент UserControl, который вы можете добавлять в проект.
Более подробнее узнать о навигации можно в специальном видеоролике:
Размещаем элементы для страницы поиска
Вернемся к проекту и закончим с размещением элементов на созданной нами странице Search.xaml. В соответствии с нашим эскизом, нам нужно разместить текстовое поле, кнопку и сетку для отображения данных.
Поместим на страницу Grid с двумя рядами: первый ряд для поисковой строки и кнопки, а второй ряд для вывода результатов. В верхнем ряду расположим элемент StackPanel и добавим на него текстовое поле и кнопку . Чтобы элементы располагались друг за другом, присвоим у StackPanel значение Orientation=Horizontal.
Далее добавим элемент DataGrid, предназначенный для работы с данными, во второй ряд сетки.
Код для страницы будет выглядеть следующем образом:
<navigation:Page x:Class="SilverlightHelloWorld.Views.Search" 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" mc:Ignorable="d" xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" d:DesignWidth="640" d:DesignHeight="480" Title="Twitter Search Page" xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"> <Grid x:Name="LayoutRoot"> <Grid.RowDefinitions> <RowDefinition Height="32"/> <RowDefinition/> </Grid.RowDefinitions> <StackPanel HorizontalAlignment="Left" Margin="0,-32,0,0" VerticalAlignment="Top" Grid.Row="1" Orientation="Horizontal"> <TextBox x:Name="SearchTerm" FontSize="14.667" Margin="0,0,10,0" Width="275" TextWrapping="Wrap"/> <Button x:Name="SearchButton" Width="75" Content="SEARCH"/> </StackPanel> <data:DataGrid x:Name="SearchResults" Margin="0,8,0,0" Grid.Row="1" /> </Grid> </navigation:Page>
Обратите внимание на запись xmlns:data в начале кода. Так можно добавлять свои элементы управления в XAML, после добавления ссылки на сборку. Сейчас приложение выглядит следующим образом (в Blend):

Для идентификации мы дали имена x:Name для текстового поля (SearchTerm), кнопки (SearchButton) и DataGrid (SearchResults). Можно приступать к написанию кода.
Изменяем UriMapper для Search.xaml
Мы практически закончили работать над интерфейсом страницы поиска. Так как она является лицом нашего приложения, то неплохо бы сделать ее главной. Внесем некоторые изменения в файле MainPage.xaml. Найдите в нем Frame и поменяйте в нем строчку таким образом, чтобы по умолчанию открывалась наша поисковая страница, а не Home.xaml:
<navigation:Frame x:Name="ContentFrame" Style="{StaticResource ContentFrameStyle}"
Source="/Search" Navigated="ContentFrame_Navigated" NavigationFailed="ContentFrame_NavigationFailed">
<navigation:Frame.UriMapper>
<uriMapper:UriMapper>
<uriMapper:UriMapping Uri="" MappedUri="/Views/Search.xaml"/>
<uriMapper:UriMapping Uri="/{pageName}" MappedUri="/Views/{pageName}.xaml"/>
</uriMapper:UriMapper>
</navigation:Frame.UriMapper>
</navigation:Frame>
Нам больше не нужен файл Home.xaml, поэтому смело удаляем его из проекта. Далее добавим новый файл History.xaml и изменим в MainPage.xaml область LinksBorder, чтобы включить ссылку на него:
<Border x:Name="LinksBorder" Style="{StaticResource LinksBorderStyle}">
<StackPanel x:Name="LinksStackPanel" Style="{StaticResource LinksStackPanelStyle}">
<HyperlinkButton x:Name="Link1" Style="{StaticResource LinkStyle}"
NavigateUri="/Search" TargetName="ContentFrame" Content="home"/>
<Rectangle x:Name="Divider1" Style="{StaticResource DividerStyle}"/>
<HyperlinkButton x:Name="Link2" Style="{StaticResource LinkStyle}"
NavigateUri="/History" TargetName="ContentFrame" Content="history"/>
<Rectangle x:Name="Divider2" Style="{StaticResource DividerStyle}"/>
<HyperlinkButton x:Name="Link3" Style="{StaticResource LinkStyle}"
NavigateUri="/About" TargetName="ContentFrame" Content="about"/>
</StackPanel>
</Border>
Сейчас программа выглядит следующим образом:

Следующие шаги
В этой статье мы познакомились с размещением элементов. Далее мы будем учиться работать с данными.
Идея:
Реклама
Диваны с производства за 3 дня - диваны .;Употребление пророщенных зерен пшеницы. Пророщенные зерна пшеницы в оздоровительном питании .;Электрогенераторы Honda: бензиновые электростанции . Продажа электростанций.

