Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторный_практикум.doc
Скачиваний:
74
Добавлен:
15.11.2019
Размер:
45.35 Mб
Скачать

5. Модификация приложения Windows Foundation Presentation: оформление элемента ListBox

Теперь осталось нарисовать новый элемент для главного окна MainWindow.xaml. Отредактируем код следующим образом:

<Window x:Class="NewListBox.MainWindow"

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

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

xmlns:local="clr-namespace:NewListBox"

Title="WPF :: Солнечная система в ListBox (C#)" Height="700" Width="700">

<!-- Ресурсы окна -->

<Window.Resources>

</Window.Resources>

<Grid HorizontalAlignment="Center" VerticalAlignment="Center" ClipToBounds="True">

</Grid>

</Window>

Для начала мы объявили привязку окна в класс NewListBox при помощи строчки в свойства кона:

xmlns:local="clr-namespace:NewListBox"

Поменяли свойство Title, высоту (700) и ширину (700) окна. Для сетки (Grid) установили положение внутренних элементов по вертикали и по горизонтали (по центру), а также задали свойство отсечения лишнего у элемента, чтобы сетка помещалась в окне. И в конце объявили пространство объектов для ресурсов окна.

Перетащим с панели инструментов элемент ListBox и очистим его содержимое. Изменим для этого элемента свойство Focusable на False, и для свойство ItemsSource пропишем Binding:

<Grid HorizontalAlignment="Center" VerticalAlignment="Center" ClipToBounds="True">

<!-- Устанавливаем сам элемент ListBox по сетке Grid -->

<ListBox ItemsSource="{Binding Source={StaticResource solarSystem}, Path=SolarSystemObjects}" Focusable="False" />

</Grid>

Для ресурсов окна сделаем следующее:

<!-- Ресурсы окна -->

<Window.Resources>

<!-- Переопределяем класс и подключаем объекты класса -->

<local:SolarSystem x:Key="solarSystem" />

<local:ConvertOrbit x:Key="convertOrbit" />

<!-- Устанавливаем шаблон для данных -->

<DataTemplate DataType="{x:Type local:SolarSystemObject}">

<Canvas Width="20" Height="20">

</Canvas>

</DataTemplate>

</Window.Resources>

Внутри поставлен элемент Canvas с размерами высоты и ширины в 20. Заполним элемент Canvas, элементом окружности и элементом изображения, тем самым создаём шаблон данных для элемента внутри ListBox (элемента списка):

<Canvas Width="20" Height="20">

<!-- Окружность орбиты (элемент Ellipse) -->

<!-- Через Binging конвертируем число типа Double Orbit из класса SolarSystemObject? Left для отступа по левому края элемента Ellipse; Top для отступа сверху -->

<Ellipse

Canvas.Left="{Binding Path=Orbit, Converter={StaticResource convertOrbit}, ConverterParameter=-1.707}"

Canvas.Top="{Binding Path=Orbit, Converter={StaticResource convertOrbit}, ConverterParameter=-0.3}"

Width="{Binding Path=Orbit, Converter={StaticResource convertOrbit}, ConverterParameter=2}"

Height="{Binding Path=Orbit, Converter={StaticResource convertOrbit}, ConverterParameter=2}"

Stroke="AliceBlue"

StrokeThickness="1" />

<!-- Через Binding получаем путь до изображения для элемента Image -->

<Image Source="{Binding Path=Image}" Width="20" Height="20">

<!-- Вставка элемента изображения для планет и размер изображения для вывода -->

<Image.ToolTip>

<!-- Подсказка при наведении мыши на элемент в ListBox -->

<StackPanel Width="250" TextBlock.FontSize="12">

<!-- Устанавливаем размер подсказки по ширине и размер шрифта -->

<!-- Используем элемент типа StackPanel для организации одной строки и вставки TextBlock -->

<TextBlock FontWeight="Bold" Text="{Binding Path=Name}" />

<StackPanel Orientation="Horizontal">

<TextBlock Text="Орбита: " />

<TextBlock Text="{Binding Path=Orbit}" />

<TextBlock Text=" а. е." />

</StackPanel>

<TextBlock Text="{Binding Path=Details}" TextWrapping="Wrap"/>

</StackPanel>

</Image.ToolTip>

</Image>

</Canvas>

Каждый элемент внутри списка будет представлен изображением, всплывающей подсказкой при наведении на изображении (название планеты, орбита, описание планеты), а также пустой окружностью проходящей позади изображения (параметры окружности определим как зависимость положение для левой верхней точки окружности внутри Canvas: слева и сверху).

Класс ConvertOrbit организовывает связь положения со значением орбиты.

Теперь установим связь шаблона данных и стиля одного элемента, а также добавим событие выделения элемента в списке через Trigger, для этого добавим новый стиль одного элемента (после закрывающего тэга </DataTemplate> и до закрывающего тэга </Window.Resources>):

</DataTemplate>

<!-- Стиль одного элемента в ListBox -->

<Style TargetType="ListBoxItem">

<Setter Property="Canvas.Left" Value="{Binding Path=Orbit, Converter={StaticResource convertOrbit}, ConverterParameter=0.707}"/>

<!-- Отступ для элемента слева -->

<Setter Property="Canvas.Bottom" Value="{Binding Path=Orbit, Converter={StaticResource convertOrbit}, ConverterParameter=0.707}"/>

<!-- Отступ для элемента снизу -->

<Setter Property="Template">

<!-- Меняем шаблон -->

<Setter.Value>

<ControlTemplate TargetType="{x:Type ListBoxItem}">

<Grid>

<!-- Вставляем в элемент ListBoxItem сетку -->

<!-- Вставляем окружность выделения -->

<Ellipse x:Name="selectedPlanet" Margin="-10" StrokeThickness="4"/>

<!-- Устанавливаем радиус окружности (-10, -10, -10, -10) и толщину пера (4) -->

<!-- ContentPresenter сообщает что окружность должна отрисовывать не поточечное, с горизонтальным положением и вертикальным положением в зависимости от шаблона первоначального элемента -->

<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>

</Grid>

<ControlTemplate.Triggers>

<!-- Событие "если выделен элемент" для ListBoxItem -->

<Trigger Property="IsSelected" Value="true">

<!-- Устанавливаем цвет и тип пера "штрих" -->

<Setter Property="Stroke" TargetName="selectedPlanet" Value="Green"/>

</Trigger>

</ControlTemplate.Triggers>

</ControlTemplate>

</Setter.Value>

</Setter>

</Style>

</Window.Resources>

В окне конструктора для MainWindow.xaml отобразится следующее:

Рис. 5. 1. Незаконченное изменения стиля элемента управления ListBox

Попробуем откомпилировать и запустить. Увидим что элементы (планеты) выделяются, появляется зелёное выделение и подсказка с полным описанием.

Наконец, изменим главный стиль ListBox (добавим XAML-код после закрывающего тэга </Style>:

</Style>

<!-- Стиль элемента управления ListBox -->

<Style TargetType="ListBox">

<Setter Property="ItemsPanel">

<Setter.Value>

<ItemsPanelTemplate>

<!-- Конечный размер ListBox, фон -->

<Canvas Width="590" Height="590" Background="Black" />

</ItemsPanelTemplate>

</Setter.Value>

</Setter>

</Style>

</Window.Resources>

Готово. В конструкторе изменится вид представления окна…