Чтение онлайн

на главную

Жанры

Язык программирования C#9 и платформа .NET5
Шрифт:

<!-- Стиль увеличивающейся кнопки -->

<Style x:Key="GrowingButtonStyle" TargetType="Button">

<Setter Property="Height" Value="40"/>

<Setter Property="Width" Value="100"/>

<Style.Triggers>

<Trigger Property="IsMouseOver" Value="True">

<Trigger.EnterActions>

<BeginStoryboard>

<Storyboard TargetProperty="Height">

<DoubleAnimation From="40" To="200"

Duration="0:0:2" AutoReverse="True"/>

</Storyboard>

</BeginStoryboard>

</Trigger.EnterActions>

</Trigger>

</Style.Triggers>

</Style>

Здесь

коллекция
Triggers
наблюдает за тем, когда свойство
IsMouseOver
возвратит значение
true
. После того как это произойдет, определяется элемент
Trigger.EnterActions
для выполнения простой раскадровки, которая заставляет кнопку за две секунды увеличиться до значения
Height
, равного
200
(и затем возвратиться к значению
Height
, равному
40
). Чтобы отслеживать другие изменения свойств, можно также добавить область
Trigger.ExitActions
и определить в ней любые специальные действия, которые должны быть выполнены, когда
IsMouseOver
изменяется на
false
.

Применение стилей в коде

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

DisableAllButton
) или еще в какой-то ситуации.

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

Button
. Давайте переделаем пользовательский интерфейс главного окна, чтобы позволить пользователю выбирать имена имеющихся стилей в элементе управления
ListBox
. На основе выбранного имени будет применен соответствующий стиль. Вот финальная разметка для элемента
DockPanel
:

<DockPanel >

<StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="0,0,0,50">

<Label Content="Please Pick a Style for this Button" Height="50"/>

<ListBox x:Name="lstStyles" Height="80" Width="150" Background="LightBlue"

SelectionChanged="comboStyles_Changed" />

</StackPanel>

<Button x:Name="btnStyle" Height="40" Width="100" Content="OK!"/>

</DockPanel>

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

ListBox
(по имени
IstStyles
) будет динамически заполняться внутри конструктора окна:

public MainWindow

{

InitializeComponent;

// Заполнить окно со списком всеми стилями для элементов Button.

lstStyles.Items.Add("GrowingButtonStyle");

lstStyles.Items.Add("TiltButton");

lstStyles.Items.Add("BigGreenButton");

lstStyles.Items.Add("BasicControlStyle");}

}

Последней задачей является обработка события

SelectionChanged
в связанном файле кода. Обратите внимание, что в следующем коде имеется возможность извлечения текущего ресурса по имени с использованием унаследованного метода
TryFindResouce
:

private void comboStyles_Changed(object sender, SelectionChangedEventArgs e)

{

//
Получить имя стиля, выбранное в окне со списком.

var currStyle=(Style)TryFindResource(lstStyles.SelectedValue);

if (currStyle==null) return;

// Установить стиль для типа кнопки.

this.btnStyle.Style=currStyle;

}

После запуска приложения появляется возможность выбора одного из четырех стилей кнопок на лету. На рис. 27.9 показано готовое приложение в действии.

Логические деревья, визуальные деревья и стандартные шаблоны

Теперь, когда вы понимаете, что собой представляют стили и ресурсы, есть еще несколько тем, которые потребуется раскрыть, прежде чем приступать к изучению построения специальных элементов управления. В частности, необходимо выяснить разницу между логическим деревом, визуальным деревом и стандартным шаблоном. При вводе разметки XAML в Visual Studio или в редакторе вроде Kaxaml разметка является логическим представлением документа XAML. В случае написания кода С#, который добавляет в элемент управления

StackPanel
новые элементы, они вставляются в логическое дерево. По существу логическое представление отражает то, как содержимое будет позиционировано внутри разнообразных диспетчеров компоновки для главного элемента
Window
(или другого корневого элемента, такого как
Page
или
NavigationWindow
).

Однако за каждым логическим деревом стоит намного более сложное представление, которое называется визуальным деревом и внутренне применяется инфраструктурой WPF для корректной визуализации элементов на экране. Внутри любого визуального дерева будут находиться полные детали шаблонов и стилей, используемых для визуализации каждого объекта, включая все необходимые рисунки, фигуры, визуальные объекты и объекты анимации.

Полезно уяснить разницу между логическим и визуальным деревьями, потому что при построении специального шаблона элемента управления на самом деле производится замена всего или части стандартного визуального дерева элемента управления собственным вариантом. Следовательно, если нужно, чтобы элемент управления

Button
визуализировался в виде звездообразной фигуры, тогда можно определить новый шаблон такого рода и подключить его к визуальному дереву
Button
. Логически тип остается тем же типом
Button
, поддерживая все ожидаемые свойства, методы и события. Но визуально он выглядит совершенно по-другому. Один лишь упомянутый факт делает WPF исключительно полезным API-интерфейсом, поскольку другие инструментальные наборы для создания кнопки звездообразной формы потребовали бы построения совершенно нового класса. В инфраструктуре WPF понадобится просто определить новую разметку.

На заметку! Элементы управления WPF часто описывают как лишенные внешности. Это относится к тому факту, что внешний вид элемента управления WPF совершенно не зависит от его поведения и допускает настройку.

Программное инспектирование логического дерева

Хотя анализ логического дерева окна во время выполнения — не слишком распространенное действие при программировании с применением WPF, полезно упомянуть о том, что в пространстве имен

System.Windows
определен класс
LogicalTreeHelper
, который позволяет инспектировать структуру логического дерева во время выполнения. Для иллюстрации связи между логическими деревьями, визуальными деревьями и шаблонами элементов управления создайте новый проект приложения WPF по имени
TreesAndTemplatesApp
.

Поделиться:
Популярные книги

Ученичество. Книга 2

Понарошку Евгений
2. Государственный маг
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ученичество. Книга 2

Безродный

Коган Мстислав Константинович
1. Игра не для слабых
Фантастика:
боевая фантастика
альтернативная история
6.67
рейтинг книги
Безродный

Неудержимый. Книга XVII

Боярский Андрей
17. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга XVII

Вечная Война. Книга VII

Винокуров Юрий
7. Вечная Война
Фантастика:
юмористическая фантастика
космическая фантастика
5.75
рейтинг книги
Вечная Война. Книга VII

Чужое наследие

Кораблев Родион
3. Другая сторона
Фантастика:
боевая фантастика
8.47
рейтинг книги
Чужое наследие

Курсант: назад в СССР 9

Дамиров Рафаэль
9. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: назад в СССР 9

Его огонь горит для меня. Том 2

Муратова Ульяна
2. Мир Карастели
Фантастика:
юмористическая фантастика
5.40
рейтинг книги
Его огонь горит для меня. Том 2

Отверженный III: Вызов

Опсокополос Алексис
3. Отверженный
Фантастика:
фэнтези
альтернативная история
7.73
рейтинг книги
Отверженный III: Вызов

Царь Федор. Трилогия

Злотников Роман Валерьевич
Царь Федор
Фантастика:
альтернативная история
8.68
рейтинг книги
Царь Федор. Трилогия

Варлорд

Астахов Евгений Евгеньевич
3. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Варлорд

Лорд Системы 13

Токсик Саша
13. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 13

Ночь со зверем

Владимирова Анна
3. Оборотни-медведи
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Ночь со зверем

Темный Кластер

Кораблев Родион
Другая сторона
Фантастика:
боевая фантастика
5.00
рейтинг книги
Темный Кластер

Сама себе хозяйка

Красовская Марианна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Сама себе хозяйка