На заметку! В подкаталоге XamlAnimations внутри Chapter_27 есть несколько файлов XAML. Скопируйте их содержимое в редактор Kaxaml, чтобы просмотреть результаты.
Большей частью создание анимации подобно всему тому, что вы уже видели: по-прежнему производится конфигурирование объекта Animation, который затем ассоциируется со свойством объекта. Тем не менее, крупное отличие связано с тем, что разметка XAML не является дружественной к вызовам методов. В результате вместо вызова BeginAnimation() используется раскадровка как промежуточный уровень.
Давайте рассмотрим полный пример анимации, определенной в терминах XAML, и подробно ее проанализируем. Приведенное далее определение XAML будет отображать окно, содержащее единственную метку. После того как объект Label загрузился в память, он начинает анимационную последовательность, во время которой размер шрифта увеличивается от 12 до 100 точек за период в четыре секунды. Анимация будет повторяться столько времени, сколько объект остается загруженным в память. Разметка находится в файле GrowLabelFont.xaml, так что его содержимое необходимо скопировать в редактор Kaxaml, нажать клавишу <F5> и понаблюдать за поведением.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="200" Width="600" WindowStartupLocation="CenterScreen"
Title="Growing Label Font!">
<StackPanel>
<Label Content="Interesting...">
<Label.Triggers>
<EventTrigger RoutedEvent="Label.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetProperty="FontSize">
<DoubleAnimation From="12" To="100" Duration="0:0:4"
RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Label.Triggers>
</Label>
</StackPanel>
</Window>
А теперь подробно разберем пример.
Роль раскадровок
При продвижении от самого глубоко вложенного элемента наружу первым встречается элемент <DoubleAnimation>, обращающийся к тем же самым свойствам, которые устанавливались в процедурном коде(From, То, Duration и RepeatBehavior):
(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})
<DoubleAnimation From="12" To="100" Duration="0:0:4"
RepeatBehavior="Forever"/>
Как упоминалось ранее, элементы Animation помещаются внутрь элемента Storyboard, применяемого для отображения объекта анимации на заданное свойство родительского типа через свойство TargetProperty, которым в данном случае является FontSize. Элемент Storyboard всегда находится внутри родительского элемента по имени BeginStoryboard:
<BeginStoryboard>
<Storyboard TargetProperty="FontSize">
<DoubleAnimation From="12" To="100" Duration="0:0:4"
RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
Роль триггеров событий
После того как элемент BeginStoryboard определен, должно быть указано действие какого-то вида, которое приведет к запуску анимации. Инфраструктура WPF предлагает несколько разных способов реагирования на условия времени выполнения в разметке, один из которых называется триггером. С высокоуровневой точки зрения триггер можно считать способом реагирования на событие в разметке XAML без необходимости в написании процедурного кода.
Обычно когда ответ на событие реализуется в С#, пишется специальный код, который будет выполнен при поступлении события. Однако триггер — всего лишь способ получить уведомление о том, что некоторое событие произошло (загрузка элемента в память, наведение на него курсора мыши, получение им фокуса и т.д.).
Получив уведомление о появлении события, можно запускать раскадровку. В показанном ниже примере обеспечивается реагирование на факт загрузки элемента Label в память. Поскольку вас интересует событие Loaded элемента Label, элемент EventTrigger помещается в коллекцию триггеров элемента Label:
<Label Content="Interesting...">
<Label.Triggers>
<EventTrigger RoutedEvent="Label.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard TargetProperty="FontSize">