#005 Анимация текста в WPF / контейнер StackPanel

Автор: Topol Воскресенье, Май 6th, 2012 Нет комментариев

Рубрика: Операционные системы

Сейчас мы поговорим о том, как при помощи WPF  можно анимировать текст. Для начала, создайте новый проект типа WinFX Windows Application и назовите его «TextAnim». Первое, что мы сделаем — это немного увеличим размер окна и разместим форму по центру. Задайте следующие свойства для формы:

Код:
Height=»480″ Width=»640″ WindowStartupLocation =»CenterScreen»


Теперь давайте вспомним наше первое WPF приложение — мы тогда говорили о том, что существует масса различных контейнеров. До этого момента мы пользовались контейнером GRID (мы к нему еще вернемся в одной из следующих статей), но сегодня нам будет удобнее воспользоваться другим контейнером, который называется StackPanel. StackPanel размещает все элементы в столбик — один над другим — создается своеобразная «невидимая таблица» с одним столбцом и любым количеством строк (количество строк = количеству элементов внутри StackPanel). Высота строк регулируется автоматически, в зависимости от высоты элемента. В одной строке размещается только один элемент. Для этого приложения я хочу разместить на форме 4 текстовых блока, каждый друг над другом. Конечно, я мог бы сделать это и в Grid, но тогда мне бы пришлось вручную форматировать их местоположение при помощи свойств Margin, Alignment. Это намного проще сделать при помощи StackPanel:

Код:
<Window x:Class=»Window1″
xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
Title=»TextAnim» Height=»480″ Width=»640″
WindowStartupLocation =»CenterScreen»
>
<StackPanel >
<TextBlock >Мой первый текстовый блок</TextBlock>
<TextBlock >Мой второй текстовый блок</TextBlock>
<TextBlock >Мой третий текстовый блок</TextBlock>
<TextBlock >Мой четвертый текстовый блок</TextBlock>
</StackPanel>
</Window>

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

Обратите внимание — я применил необычный способ задания основного свойства для текстового блока. В данном случае это свойство TEXT. Я написал его значение между конструкторами элемента <TextBlock>. Такая форма записи равносильна следующей: <TextBlock Text=»Мой текстовый блок»/> Так же можно поступать и с некоторыми другими элементами, например, со знакомым вам элементом <Button>.

Давайте немного изменим внешний вид наших надписей. Добавьте эти свойства к каждому текстовому блоку: FontFamily =»SegoeUI» FontSize =»38″. Обратите внимание, что изменив размер наших надписей, при использовании StackPanel нам не нужно заботиться о том, чтобы вручную форматировать их расположение (как в случае с Grid) — StackPanel делает это за нас, засчет «виртуальных строк». Также давайте добавим к каждому текстовому блоку свойство Foreground, но теперь с любыми, но разными значениями, например вот так:

Код:
<StackPanel >
<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Foreground =»Green»>Мой первый текстовый блок</TextBlock>

<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Foreground=»Red» >Мой второй текстовый блок</TextBlock>

<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Foreground =»Blue» >Мой третий текстовый блок</TextBlock>

<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Foreground =»Gold» >Мой четвертый текстовый блок</TextBlock>
</StackPanel>

Запустите программу и посмотрите, что получилось. Теперь давайте займемся анимацией наших текстовых блоков. Если вы помните нашу статью № 003, посвященную богатой графике и введению в анимацию — то вы знаете, что за интерактив элемента отвечает его свойство Triggers. Давайте зададим имена для каждого TextBlock-а. Для первого Name=»MyWipedText», для второго Name=»MyFadingText», для третьего Name=»MyChangingColorText» и для четвертого Name=»MyRotatingText». Как и в случае, когда мы анимировали прямоугольник в третьей статье, анимация будет начинаться при загрузке элемента, поэтому добавьте соответствующий код для каждого текстового блока, вот так:

Код:
<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Foreground =»Green»
Name=»MyWipedText»>Мой первый текстовый блок

<TextBlock.Triggers>
<EventTrigger RoutedEvent=»TextBlock.Loaded»>
<BeginStoryboard>
<Storyboard>

</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

Первый текстовый блок будет уничтожаться справа налево и восстанавливаться, поэтому внутри блока <Storyboard></Storyboard> для первого блока внесите такой код:

Код:
<DoubleAnimation
Storyboard.TargetName=»MyWipedText»
Storyboard.TargetProperty=»(TextBlock.Width)»
To=»0.0″ Duration=»0:0:10″
AutoReverse=»True» RepeatBehavior=»Forever» />

Думаю вы без труда разберетесь с этим кодом (для более подробной информации смотрите статью 003). Однако если вы сейчас попробуете запустить проект, вы получите сообщение об ошибке. Почему? Дело в том, что в данном случае мы подвергаем анимации свойство Width нашего текстового блока. Свойство To указывает, что ширина должна уменьшиться до 0, а свойство AutoReverse что ширина должна будет восстановиться до исходного значения. Но у нас нет исходного значения! С этим и связана ошибка. Поэтому, чтобы ее решить, давайте просто добавим Width=»480″ в описание текстового блока. Запустите программу и посмотрите на результат:

Да, анимация работает, но так и хочется крикнуть: «Эй, я не заказывал выравнивание по центру!» Давайте добавим в описание нашего первого блока еще и такое свойство HorizontalAlignment =»Left». Запускаем и смотрим:

Мы достигли желаемого эффекта! На всякий случай, полный код первого блока:

Код:
<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Foreground =»Green»
Name=»MyWipedText» Width=»480″
HorizontalAlignment =»Left»>Мой первый текстовый блок

<TextBlock.Triggers>
<EventTrigger RoutedEvent=»TextBlock.Loaded»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»MyWipedText»
Storyboard.TargetProperty=»(TextBlock.Width)»
To=»0.0″ Duration=»0:0:10″
AutoReverse=»True» RepeatBehavior=»Forever» />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

Давайте перейдем ко второй надписи — здесь мы хотим, чтобы надпись плавно исчезала и вновь появлялась. Для этого будем анимировать свойство прозрачности Opacity — оно принимает значения от 0 до 1. Например если вы хотите задать прозрачность 50%, то значением свойства Opacity будет 0.5 — добавьте этот код внутри блока <Storyboard></Storyboard> для нашего второго элемента:

Код:
<DoubleAnimation
Storyboard.TargetName=»MyFadingText»
Storyboard.TargetProperty=»(TextBlock.Opacity)»
From=»1.0″ To=»0.0″ Duration=»0:0:5″
AutoReverse=»True» RepeatBehavior=»Forever» />

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

Переходим к третьему текстовому блоку. Здесь бутет немного интересней. Я хочу, чтобы третья надпись меняла свой цвет. Для этого объектом анимации будет не сам TextBlock, а его заливочная кисть! Сейчас заливочная кисть не определена, поэтому давайте внесем кое-какие коррективы. Удалите свойство Foreground из описания третьего текстового блока:

После этого внесите этот код в тело надписи (помните, нечто подобное мы делали в статье 003?) :

Пусть вас не смущает что имя для кисти типа SolidColorBrush мы задали при помощи несколько необычного оператора x:Name. Теперь мы готовы к внесению кода анимации. Как обычно, внутри уже подготовленного блока <Storyboard></Storyboard> вносим такой код:

Код:
<ColorAnimation
Storyboard.TargetName=»MySolidColorBrush»
Storyboard.TargetProperty=»Color»
From=»DarkOrange» To=»SteelBlue» Duration=»0:0:5″
AutoReverse=»True» RepeatBehavior=»Forever» />

Обратите внимание, что теперь мы использовали новый тип анимации ColorAnimation — он подходит для анимирования кистей заливки и других подобных задач. Также посмотрите, что мы использовали свойство From — оно явно задало начальное значение для анимации. Запустите проект и посмотрите как красиво меняется цвет у нашей третьей надписи. На всякий случай полный код третьего элемента:

Код:
<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Name=»MyChangingColorText»>
Мой третий текстовый блок

<TextBlock.Foreground>
<SolidColorBrush x:Name=»MySolidColorBrush» Color=»Blue» />
</TextBlock.Foreground>

<TextBlock.Triggers>
<EventTrigger RoutedEvent=»TextBlock.Loaded»>
<BeginStoryboard>
<Storyboard>

<ColorAnimation
Storyboard.TargetName=»MySolidColorBrush»
Storyboard.TargetProperty=»Color»
From=»DarkOrange» To=»SteelBlue» Duration=»0:0:5″
AutoReverse=»True» RepeatBehavior=»Forever» />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

У нас остался четвертый элемент — мы заставим его вращаться! В WPF за различные изменения положения, формы и других подобных характеристик объекта отвечает свойство RenderTransform. Чтобы заставить надпись вертеться, анимации мы подвергнем характеристику Angle (угол) свойства RenderTransform. Добавьте такой код в тело четвертой надписи:

Внимательно изучите комментарии на картинке выше. Теперь мы готовы для создания анимации. Думаю вы уже догадались, что код анимации мы внесем между блоков <Storyboard></Storyboard> нашей четвертой надписи. Вот этот код:

Код:
<DoubleAnimation
Storyboard.TargetName=»MyRotateTransform»
Storyboard.TargetProperty=»(RotateTransform.Angle)»
From=»0.0″ To=»360″ Duration=»0:0:10″
RepeatBehavior=»Forever» />

Тут все очень просто — мы меняем угол с 0 градусов (From) до 360 градусов (To) , чем и заставляем надпись вращаться вокруг своей оси. Запустите проект и посмотрите, что получилось:

Мы научились на примере текстовых надписей типа TextBlock создавать анимации различного типа. Обратите внимание на то, как просто создать сложные эффекты в Windows Presentation Foundation. Система позволяет одновременно воспроизводиться сразу любому количеству элементов и анимаций, при этом ваше окно полностью откликается на любые события. Представьте, сколько усилий потребовало бы от программиста, чтобы создать нечто подобное в обычном .NET 2.0 !

В завершение статьи, традиционно привожу полный листинг программы:

Код:
<Window x:Class=»Window1″
xmlns=»http://schemas.microsoft.com/winfx/2006/xaml/presentation»
xmlns:x=»http://schemas.microsoft.com/winfx/2006/xaml»
Title=»TextAnim» Height=»480″ Width=»640″
WindowStartupLocation =»CenterScreen»
>
<StackPanel >
<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Foreground =»Green»
Name=»MyWipedText» Width=»480″
HorizontalAlignment =»Left»>Мой первый текстовый блок

<TextBlock.Triggers>
<EventTrigger RoutedEvent=»TextBlock.Loaded»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»MyWipedText»
Storyboard.TargetProperty=»(TextBlock.Width)»
To=»0.0″ Duration=»0:0:10″
AutoReverse=»True» RepeatBehavior=»Forever» />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Foreground=»Red»
Name=»MyFadingText»>
Мой второй текстовый блок

<TextBlock.Triggers>
<EventTrigger RoutedEvent=»TextBlock.Loaded»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»MyFadingText»
Storyboard.TargetProperty=»(TextBlock.Opacity)»
From=»1.0″ To=»0.0″ Duration=»0:0:5″
AutoReverse=»True» RepeatBehavior=»Forever» />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
</TextBlock>

<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Name=»MyChangingColorText»>
Мой третий текстовый блок

<TextBlock.Foreground>
<SolidColorBrush x:Name=»MySolidColorBrush» Color=»Blue» />
</TextBlock.Foreground>

<TextBlock.Triggers>
<EventTrigger RoutedEvent=»TextBlock.Loaded»>
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetName=»MySolidColorBrush»
Storyboard.TargetProperty=»Color»
From=»DarkOrange» To=»SteelBlue» Duration=»0:0:5″
AutoReverse=»True» RepeatBehavior=»Forever» />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>

</TextBlock>

<TextBlock FontFamily =»SegoeUI» FontSize =»38″
Foreground =»Gold»
Name=»MyRotatingText»>
Мой четвертый текстовый блок

<TextBlock.RenderTransform>
<RotateTransform x:Name=»MyRotateTransform»
Angle=»0″ CenterX=»230″ CenterY=»25″/>
</TextBlock.RenderTransform>

<TextBlock.Triggers>
<EventTrigger RoutedEvent=»TextBlock.Loaded»>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName=»MyRotateTransform»
Storyboard.TargetProperty=»(RotateTransform.Angle)»
From=»0.0″ To=»360″ Duration=»0:0:10″
RepeatBehavior=»Forever» />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>

</TextBlock>

</StackPanel
</Window>

 

Источник: thevista.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты