Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Wpf-АК11.doc
Скачиваний:
3
Добавлен:
01.03.2025
Размер:
3.47 Mб
Скачать

6. Элемент управления DockPanel

Элемент управления DockPanel — один из самых полезных элементов управления макета. Он, вероятно, будет использоваться как базовый в каждом новом окне. По сути, с помощью DockPanel (или двух таких элементов) можно реализовать основной макет большинства современных приложений. Можно закрепить строку меню сверху, затем левую и правую области основного содержимого, а строку состояния снизу. Как правило, закрепление любого дочернего элемента в элементе DockPanel управляется следующим присоединенным свойством зависимости:

  • DockPanel.Dock

Этому свойству можно присвоить значения Left, Right, Top или Bottom. Есть еще одно полезное свойство (обычное свойство CLR) элемента управления DockPanel, называемое LastChildFill. Если этому свойству присвоено значение true, последний добавленный дочерний элемент будет занимать все оставшееся свободное пространство. Оно переопределяет свойство DockPanel.Dock, которое может быть уже задано дочерним элементом.

На рис. 3.4 показан элемент управления DockPanel с двумя дочерними элементами, один из которых закреплен сверху, а другой занимает все оставшееся свободное пространство.

Рис. 3.4 - Элемент управления DockPanel

Пример кода XAML:

<Window

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   x:Class="WPF_Tour_Beginners_Layout.DockPanelDEMO"

   x:Name="Window"

   Title="DockPanelDEMO"

   WindowStartupLocation="CenterScreen"

   Width="640" Height="480">

   <DockPanel Width="Auto" Height="Auto" LastChildFill="True">

       <Rectangle Fill="CornflowerBlue" Stroke="CornflowerBlue"

           Height="20" DockPanel.Dock="Top"/>

       <Rectangle Fill="Orange" Stroke="Orange" />

   </DockPanel>

</Window>

ПримеркодаC#:

DockPanel dp = new DockPanel();

dp.LastChildFill = true;

//Этоэквивалентно Width="Auto" в XAML, кромеэлементов GridColumn Width/Height и GridRow Width/Height

dp.Width = Double.NaN;

dp.Height = Double.NaN;

//добавить элемент WrapPanel в качестве единственного дочернего элемента Window

this.Content = dp;

//Добавитьпрямоугольники

Rectangle rTop = new Rectangle();

rTop.Fill = new SolidColorBrush(Colors.CornflowerBlue);

rTop.Stroke = new SolidColorBrush(Colors.CornflowerBlue);

rTop.Height = 20;

dp.Children.Add(rTop);

rTop.SetValue(DockPanel.DockProperty,Dock.Top);

Rectangle rFill = new Rectangle();

rFill.Fill = new SolidColorBrush(Colors.Orange);

rFill.Stroke = new SolidColorBrush(Colors.Orange);

dp.Children.Add(rFill);

7. Элемент Grid

Элемент Grid— самый сложный элемент управления макета в WPF в этой работе. Он немного похож на табличный элемент управления HTML, в котором можно задавать строки и столбцы, а ячейки могут содержать несколько строк или столбцов. Для свойств Width и Height столбцов и строк может применяться странный синтаксис с использованием символа звездочки (*), предоставляемый с помощью класса GridLength. Его можно представить в виде процентного разделителя свободного места:

<Grid.ColumnDefinitions>

   <ColumnDefinition Width="40"/>

   <ColumnDefinition Width="*"/>

   <ColumnDefinition Width="2*"/>

</Grid.ColumnDefinitions>

Здесьвэлементе Grid объявленытриэлемента ColumnDefinition. Ширина первого элемента ColumnDefinition зафиксирована (40 пикселей), а оставшееся пространство делится между двумя другими элементами ColumnDefinition, причем последнему из них выделяется в два раза больше места, чем предпоследнему. Этот же принцип применяется в отношении RowDefinition.

Для уведомления системы макета WPF о ячейке, к которой относятся дочерние элементы элемента Grid, используются следующие присоединенные свойства зависимости (нумерация индекса начинается с 0):

  • Grid.Column

  • Grid.Row

А для задания количества строк или столбцов, занимаемых ячейкой, используются следующие присоединенные свойства зависимости (значения начинаются с 1):

  • Grid.ColumnSpan

  • Grid.RowSpan

Элемента управления Grid можно имитировать практически любые другие элементы управления макета.

Рассмотрим пример использования Grid. На рисунке 3.5 показан элемент управления Grid с тремя столбцами, одной строкой и двумя дочерними элементами. Первый дочерний элемент находится в столбце 1, а второй занимает столбцы 2 и 3, поскольку его свойству Grid.ColumnSpan присвоено значение 2.

Рис. 3.5 - Элемент управления Grid

Пример кода XAML:

<Window

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   x:Class="WPF_Tour_Beginners_Layout.GridDEMO"

   x:Name="Window"

   Title="GridDEMO"

   WindowStartupLocation="CenterScreen"

   Width="640" Height="480">

   <Grid Width="Auto" Height="Auto" >

       <Grid.ColumnDefinitions>

           <ColumnDefinition Width="40"/>

           <ColumnDefinition Width="*"/>

           <ColumnDefinition Width="2*"/>

       </Grid.ColumnDefinitions>

       <Rectangle Fill="Aqua" Grid.Column="0" Grid.Row="0"/>

       <Rectangle Fill="Plum" Grid.Column="1" Grid.ColumnSpan="2"/>

   </Grid>

</Window>

Пример кодаC#

Grid grid = new Grid();

grid.Width = Double.NaN;   //this is the same as Width="Auto" in XAML

grid.Height = Double.NaN;  //this is the same as Height="Auto" in XAML

//добавить элемент Grid в качестве единственного дочернего элемента Window

this.Content = grid;

//Столбец 1

ColumnDefinition cd1 = new ColumnDefinition();

cd1.Width = new GridLength(40);

grid.ColumnDefinitions.Add(cd1);

//Столбец 2

ColumnDefinition cd2 = new ColumnDefinition();

cd2.Width = new GridLength(1, GridUnitType.Star);

grid.ColumnDefinitions.Add(cd2);

//Столбец 3

ColumnDefinition cd3 = new ColumnDefinition();

cd3.Width = new GridLength(2, GridUnitType.Star);

grid.ColumnDefinitions.Add(cd3);

//Добавимячейкивэлемент grid

Rectangle r1c1 = new Rectangle();

r1c1.Fill = new SolidColorBrush(Colors.Aqua);

r1c1.SetValue(Grid.ColumnProperty, 0);

r1c1.SetValue(Grid.RowProperty, 0);

grid.Children.Add(r1c1);

Rectangle r1c23 = new Rectangle();

r1c23.Fill = new SolidColorBrush(Colors.Plum);

r1c23.SetValue(Grid.ColumnProperty, 1);

r1c23.SetValue(Grid.ColumnSpanProperty, 2);

grid.Children.Add(r1c23);

Возьмем типичный макет, в котором есть строка меню сверху, основная область содержимого и строка состояния внизу. Попробуем воспроизвести такой макет (созданный в виде простого приложения WinForm).

Рис. 3.6 - Шаблон приложения

Для выполнения этого упражнения вам потребуются элементы управления StackPanel, DockPanel и Grid.

<Window x:Class="WPF_Tour_Beginners_Layout.PuttingItAllTogether"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   WindowStartupLocation="CenterScreen"

   Title="PuttingItAllTogether" Width="640" Height="480" >

   <DockPanel Width="Auto" Height="Auto" LastChildFill="True">

       <!--Верхняяобластьменю-->

       <Menu Width="Auto" Height="20" Background="#FFA9D1F4"

           DockPanel.Dock="Top">

           <!--Меню File -->

           <MenuItem Header="File">

               <MenuItem Header="Save"/>

               <Separator/>

               <MenuItem Header="Exit"/>

           </MenuItem>

           <!--Меню About-->

           <MenuItem Header="Help">

               <MenuItem Header="About"/>

           </MenuItem>

       </Menu>

       <!--Нижняя область строки состояния объявляется до средней области,

       поскольку я хотел заполнить весь низ окна,

       что не удалось бы сделать при наличии зафиксированной слева панели-->

       <StackPanel Width="Auto" Height="31" Background="#FFCAC5C5"

           Orientation="Horizontal" DockPanel.Dock="Bottom">

           <Label Width="155" Height="23" Content="Status Bar Message...."

           FontFamily="Arial" FontSize="10"/>

       </StackPanel>

       <!--Левая область основного содержимого-->

       <StackPanel Width="136" Height="Auto" Background="White">

           <Button Margin="5,5,5,5" Width="Auto" Height="26" Content="button1"/>

           <Button Width="126" Height="26" Content="button2" Margin="5,5,5,5"/>

           <Button Width="126" Height="26" Content="button3" Margin="5,5,5,5"/>

       </StackPanel>

       <!--Правая область основного содержимого. ОБРАТИТЕ ВНИМАНИЕ, что этот элемент Grid — последний дочерний элемент,

       поэтому он занимает все оставшееся место -->

       <Grid Width="Auto" Height="Auto" Background="#FFCC9393">

           <Grid.ColumnDefinitions>

               <ColumnDefinition Width="*"/>

               <ColumnDefinition Width="*"/>

           </Grid.ColumnDefinitions>

           <Grid.RowDefinitions>

               <RowDefinition Height="*"/>

               <RowDefinition Height="*"/>

           </Grid.RowDefinitions>

           <Rectangle Fill="Aqua" Margin="10,10,10,10" Grid.Row="0" Grid.Column="0"/>

           <Rectangle Fill="Aqua" Margin="10,10,10,10" Grid.Row="0" Grid.Column="1"/>

           <Rectangle Fill="Aqua" Margin="10,10,10,10" Grid.Row="1" Grid.Column="0"/>

           <Rectangle Fill="Aqua" Margin="10,10,10,10" Grid.Row="1" Grid.Column="1"/>

       </Grid>

   </DockPanel>

</Window>

В результате получается следующее окно (рис. 3.7).

Рис. 3.7 - Результирующий интерфейс приложения

Элемент Grid для правой области содержимого должен быть последним объявленным дочерним элементом, чтобы занимать оставшееся пространство, которое должен заполнить родительский элемент DockPanel, поскольку LastChildFill="True".

Элемент StackPanel, используемый для создания строки состояния, должен находиться до любого другого дочернего элемента с объявленными значениями DockPanel.Dock="Left" или DockPanel.Dock="Right". Если бы строке состояния StackPanel предшествовал другой элемент управления, строка состояния StackPanel не смогла бы занимать всю доступную ширину, поскольку это место было бы занято дочерним элементом со значениями свойства DockPanel.Dock="Left" или DockPanel.Dock="Right".

Пользовательские макеты. Также можно создавать собственные панели, реализующие все возможности пользовательских.

Если вам нужна собственная пользовательская панель, нужно создать класс, производный от System.Windows.Controls.Panel, и применить два переопределения: MeasureOverrideиLayoutOverride. Они реализуют двухпроходную систему макета, где на этапе Measure родительский элемент обращается к вашему элементу,чтобы узнать,сколько места ему требуется. Ваш элемент,как правило,опрашивает дочерние элементы о необходимом месте и передает полученную информацию родительскому элементу. На втором проходе кто-нибудь принимает решение о размерах и передает конечный размер в метод Arrange Override, где вы сообщаете своим дочерним элементам их размер и размещаете их. Обратите внимание,что при любом действии, которое влияет на макет (например, при изменении размера окна), все эти операции повторятся с новыми размерами.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]