Наличие встроенных возможностей анимации представляют одну из ключевых особенностей платформы WPF. Анимации в WPF - это действиетельно мощное средство, которое при этом очень легко использовать. Но перед тем, как перейти к созданию анимаций, сразу надо сказать об ограничениях:
Одна анимация выполняется только для одного свойства зависимостей
Для анимации свойства необходим класс анимации, который бы поддерживал тип этого свойства. Например, для изменения таких свойств, как длина, ширина, которые представляют тип double
, предназначен класс
DoubleAnimation. Для изменения цвета фона или шрифта - ColorAnimation, для изменения свойства Margin
- ThiknessAnimation.
За анимацию в WPF отвечает пространство имен System.Windows.Media.Animation
. Оно содержит довольно большой набор классов, позволяющих
анимировать различные свойства. Но в реальности все классы анимаций можно разделить условно на три группы:
Классы, которые производят линейную интерполяцию значений, благодаря чему при анимации свойство плавно изменяет свое значение. Как правило, такие классы
называются по шаблону TypeAnimation
, где Type
- тип данных, которое представляет анимируемое свойства, например, DoubleAnimation
:
ByteAnimation
ColorAnimation
DecimalAnimation
DoubleAnimation
Int16Animation
Int32Animation
Int64Animation
PointAnimation
Point3DAnimation
QuarternionAnimation
RectAnimation
Rotation3DAnimation
SingleAnimation
SizeAnimation
ThicknessAnimation
VectorAnimation
Vector3DAnimation
Классы, которые производят анимацию по ключевым кадрам или фреймам (покадровая анимация). Такие классы, как правило, называются по шаблону
TypeAnimationUsingKeyFrames
, например, DoubleAnimationUsingKeyFrames
BooleanAnimationUsingKeyFrames
ByteAnimationUsingKeyFrames
CharAnimationUsingKeyFrames
ColorAnimationUsingKeyFrames
DecimalAnimationUsingKeyFrames
DoubleAnimationUsingKeyFrames
Int16AnimationUsingKeyFrames
Int32AnimationUsingKeyFrames
Int64AnimationUsingKeyFrames
MatrixAnimationUsingKeyFrames
ObjectAnimationUsingKeyFrames
PointAnimationUsingKeyFrames
Point3DAnimationUsingKeyFrames
QuarternionAnimationUsingKeyFrames
RectAnimationUsingKeyFrames
Rotation3DAnimationUsingKeyFrames
SingleAnimationUsingKeyFrames
SizeAnimationUsingKeyFrames
StringAnimationUsingKeyFrames
ThicknessAnimationUsingKeyFrames
VectorAnimationUsingKeyFrames
Vector3DAnimationUsingKeyFrames
Классы, которые используют для анимации объект PathGeometry. Такие классы, как правило, называются по шаблону
TypeAnimationUsingPath
, например, DoubleAnimationUsingPath
DoubleAnimationUsingPath
MatrixAnimationUsingPath
PointAnimationUsingPath
Анимацию можно создать и использовать как декларативно в коде XAML, так и программно в коде C#.
Пусть в XAML определена кнопка:
<Button x:Name="helloButton" Width="70" Height="30" Content="Hello" />
Проанимируем ее свойство Width
:
using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Animation; namespace AnimationApp { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); DoubleAnimation buttonAnimation = new DoubleAnimation(); buttonAnimation.From = helloButton.ActualWidth; buttonAnimation.To = 150; buttonAnimation.Duration = TimeSpan.FromSeconds(3); helloButton.BeginAnimation(Button.WidthProperty, buttonAnimation); } } }
В данном случае мы сначала задаем тип анимации и создаем ее. Поскольку изменяется свойство Width, это будет DoubleAnimation.
У любого класса линейной анимации есть набор свойств, с помощью которых мы можем управлять анимацией:
From: начальное значение, с которого будет начинается анимация
To: конечное значение
Duration: время анимации в виде объекта TimeSpan
By: значение, которое указывает, насколько должно увеличиться анимируемое свойство. Свойство By используется вместо свойства To
RepeatBehavior: позволяет установить, как анимация будет повторяться
AccelerationRatio: задает ускорение анимации
DecelerationRatio: устанавливает замедление анимации
SpeedRatio: устанавливает скорость анимации. По умолчанию значение 1.0
AutoReverse: при значении true анимация выполняется в противоположную сторону
FillBehavior: определеяет поведение после окночания анимации. Если оно имеет значение Stop
, то после окончания
анимации объект возвращает прежние значения: buttonAnimation.FillBehavior = FillBehavior.Stop
. Если же оно имеет значение HoldEnd
,
то анимация присваивает анимируемому свойству новое значение.
Чтобы запустить анимацию, у элемента вызывается метод BeginAnimation()
. В этот метод передается свойство зависимости, которое надо анимировать, и сам объект анимации.
В данном случае произойдет изменение ширины кнопки от текущего значения до 150 пикселей. И данное изменение будет длиться 3 секунды.
Если мы хотим повторения анимации, можно использовать свойство RepeatBehavior:
DoubleAnimation buttonAnimation = new DoubleAnimation(); buttonAnimation.From = helloButton.ActualWidth; buttonAnimation.To = 150; buttonAnimation.Duration = TimeSpan.FromSeconds(3); buttonAnimation.RepeatBehavior = new RepeatBehavior(2); helloButton.BeginAnimation(Button.WidthProperty, buttonAnimation);
В данном случае анимация будет повторяться два раза. Также мы можем задать время повторения:
buttonAnimation.Duration = TimeSpan.FromSeconds(3); buttonAnimation.RepeatBehavior = new RepeatBehavior(TimeSpan.FromSeconds(7));
Здесь время повторения - 7 секунд. Анимация длится 3 секунды, а это значит, что будет 7 / 3 повторений: два полноценных повторения и в последнем случае ширина увелится только до трети требуемой ширины.
Чтобы задать плавное изменение свойства в обратную сторону, применим свойство AutoReverse:
buttonAnimation.AutoReverse = true; buttonAnimation.RepeatBehavior = new RepeatBehavior(5);
При завершении анимации генерируется событие Completed, которое мы можем обработать:
public MainWindow() { InitializeComponent(); DoubleAnimation buttonAnimation = new DoubleAnimation(); buttonAnimation.From = helloButton.ActualWidth; buttonAnimation.To = 150; buttonAnimation.Duration = TimeSpan.FromSeconds(5); buttonAnimation.Completed += ButtonAnimation_Completed; helloButton.BeginAnimation(Button.WidthProperty, buttonAnimation); } private void ButtonAnimation_Completed(object sender, EventArgs e) { MessageBox.Show("Анимация завершена"); }
Одна анимация может работать только с одним свойством объекта. Однако если нам надо анимировать сразу несколько свойств, то мы можем задать для каждоо свой объект анимации:
// анимация для ширины DoubleAnimation widthAnimation = new DoubleAnimation(); widthAnimation.From = helloButton.ActualWidth; widthAnimation.To = 150; widthAnimation.Duration = TimeSpan.FromSeconds(5); // анимация для высоты DoubleAnimation heightAnimation = new DoubleAnimation(); heightAnimation.From = helloButton.ActualHeight; heightAnimation.To = 60; heightAnimation.Duration = TimeSpan.FromSeconds(5); helloButton.BeginAnimation(Button.WidthProperty, widthAnimation); helloButton.BeginAnimation(Button.HeightProperty, heightAnimation);