Общие сведения о Storyboard
В этом разделе показано, как использовать Storyboard объектов для создания и применения анимаций. Он описывает, как интерактивно манипулировать Storyboard объектов и описывает синтаксис косвенного выбора свойств.
Предварительные требования
Для понимания этого раздела необходимо ознакомиться с различными типами анимации и их основными возможностями. Общие сведения об анимации см. в разделе Общие сведения об эффектах анимации. Вы также должны знать, как использовать вложенные свойства. Дополнительные сведения о вложенных свойствах см. в разделах Общие сведения о вложенных свойствах.
Что такое раскадровка?
Анимация — не единственный удобный тип временной шкалы. Существуют другие классы временной шкалы, с помощью которых вы сможете создать наборы временных шкал и применить временные шкалы к свойствам. Временные шкалы контейнера являются производными от TimelineGroup класса и включать ParallelTimeline и Storyboard.
Объект Storyboard — это тип временной шкалы контейнера, который содержит сведения для временных шкал, он содержит. Раскадровка может содержать любой тип Timeline, включая другие временные шкалы контейнера и анимации. Storyboard объекты позволяют объединять временные шкалы, которые влияют на различные объекты и свойства в одно дерево временной шкалы, упрощая организацию и управление сложным поведением времени. Например, предположим, что вам необходима кнопка, которая выполняет следующие три действия.
Увеличивается и изменяет цвет, когда пользователь выбирает кнопку.
Сжимается, а затем увеличивается до исходного размера, когда пользователь нажимает на кнопку.
Сжимается и изменяет яркость до 50-процентной прозрачности, если кнопка становится недоступной.
В этом случае у вас есть несколько наборов анимаций, которые применяются к одному объекту и которые требуется воспроизводить в разное время в зависимости от состояния кнопки. Storyboard объекты позволяют упорядочить анимации и применить их в группах для одного или нескольких объектов.
Где можно использовать раскадровку?
Объект Storyboard может использоваться для анимации свойства зависимостей анимируемых классов (Дополнительные сведения о том, что делает класс анимируемым, см. в разделе Общие сведения об анимации). Однако поскольку раскадровка является функцией уровня платформы, объект должен принадлежать к NameScope из FrameworkElement или FrameworkContentElement.
Например, можно использовать Storyboard для следующих целей:
Анимация SolidColorBrush (не являющийся элементом платформы), который закрашивает фон кнопки (разновидность FrameworkElement),
Анимация SolidColorBrush (не являющийся элементом платформы), которая закрашивает заполнения GeometryDrawing (не являющийся элементом платформы) отображается с помощью Image (FrameworkElement).
В коде, анимация SolidColorBrush объявляется с помощью класса, который также содержит FrameworkElement, если SolidColorBrush зарегистрировано, его имя FrameworkElement.
Тем не менее, невозможно использовать Storyboard для анимации SolidColorBrush , не зарегистрировало его именем FrameworkElement или FrameworkContentElement, или который не использовался, чтобы задать свойство FrameworkElement или FrameworkContentElement.
Применение анимации с помощью раскадровки
Чтобы использовать Storyboard для создания и применения анимаций, можно добавить анимации в качестве дочерних временных шкал объекта Storyboard. Storyboard Класс предоставляет Storyboard.TargetName и Storyboard.TargetProperty присоединенных свойств. Эти свойства используются для указания целевого объекта и целевого свойства анимации.
Чтобы применить анимацию к целевым объектам, началом Storyboard с помощью действия триггера или метода. В XAML, использовании BeginStoryboard со EventTrigger, Trigger, или DataTrigger. В коде, можно также использовать Begin метод.
В следующей таблице показаны различные где каждого Storyboard начать прием поддерживается: для каждого экземпляра, стиль, шаблон элемента управления и шаблон данных. Применение к конкретным экземплярам подразумевает применение анимации или раскадровки непосредственно к экземплярам объектов, а не в стилях, шаблонах элементов управления или шаблонах данных.
Раскадровка запускается с помощью метода... | Применение к конкретным экземплярам | Стиль | Шаблон элемента управления | Шаблон данных | Пример |
---|---|---|---|---|---|
BeginStoryboard и EventTrigger | Да | Да | Да | Да | Анимация свойства с помощью раскадровки |
BeginStoryboard и свойство Trigger | Нет | Да | Да | Да | Запуск анимации при изменении значения свойства |
BeginStoryboard и DataTrigger | Нет | Да | Да | Да | Практическое руководство. Запуск анимации при изменении данных |
Begin метод | Да | Нет | Нет | Нет | Анимация свойства с помощью раскадровки |
В следующем примере используется Storyboard для анимации Width из Rectangle элемент и Color из SolidColorBrush используется для рисования Rectangle.
<!-- This example shows how to animate with a storyboard.-->
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Microsoft.Samples.Animation.StoryboardsExample"
WindowTitle="Storyboards Example">
<StackPanel Margin="20">
<Rectangle Name="MyRectangle"
Width="100"
Height="100">
<Rectangle.Fill>
<SolidColorBrush x:Name="MySolidColorBrush" Color="Blue" />
</Rectangle.Fill>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="Width"
From="100" To="200" Duration="0:0:1" />
<ColorAnimation
Storyboard.TargetName="MySolidColorBrush"
Storyboard.TargetProperty="Color"
From="Blue" To="Red" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Data;
using System.Windows.Shapes;
using System.Windows.Input;
namespace Microsoft.Samples.Animation
{
public class StoryboardsExample : Page
{
public StoryboardsExample()
{
this.WindowTitle = "Storyboards Example";
StackPanel myStackPanel = new StackPanel();
myStackPanel.Margin = new Thickness(20);
Rectangle myRectangle = new Rectangle();
myRectangle.Name = "MyRectangle";
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
this.RegisterName(myRectangle.Name, myRectangle);
myRectangle.Width = 100;
myRectangle.Height = 100;
SolidColorBrush mySolidColorBrush = new SolidColorBrush(Colors.Blue);
this.RegisterName("MySolidColorBrush", mySolidColorBrush);
myRectangle.Fill = mySolidColorBrush;
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 100;
myDoubleAnimation.To = 200;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation,
new PropertyPath(Rectangle.WidthProperty));
ColorAnimation myColorAnimation = new ColorAnimation();
myColorAnimation.From = Colors.Blue;
myColorAnimation.To = Colors.Red;
myColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myColorAnimation, "MySolidColorBrush");
Storyboard.SetTargetProperty(myColorAnimation,
new PropertyPath(SolidColorBrush.ColorProperty));
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
myStoryboard.Children.Add(myColorAnimation);
myRectangle.MouseEnter += delegate(object sender, MouseEventArgs e)
{
myStoryboard.Begin(this);
};
myStackPanel.Children.Add(myRectangle);
this.Content = myStackPanel;
}
}
}
В следующих разделах описываются TargetName и TargetProperty присоединенных свойств более подробно.
Элементы целевой платформы, элементы содержимого платформы и объекты Freezable
В предыдущем разделе упоминалось, что для поиска целевого объекта анимации необходимо знать имя целевого объекта и анимируемое свойство. Указание свойства для анимации выполняется очень легко: просто задайте Storyboard.TargetProperty именем анимируемое свойство. Укажите имя объекта, свойство которого вы хотите анимировать, установив Storyboard.TargetName свойство анимации.
Для TargetName работы свойства целевого объекта должен иметь имя. Назначение имени для FrameworkElement или FrameworkContentElement в XAML отличается от присваивания имени Freezable объекта.
Элементами платформы являются классы, наследующие от FrameworkElement класса. Примеры элементов платформы включают Window, DockPanel, Button, и Rectangle. По существу все окна, панели и элементы управления являются элементами. Элементами содержимого платформы являются классы, наследующие от FrameworkContentElement класса. Примеры элементов содержимого платформы включают FlowDocument и Paragraph. Если вы не уверены, что этот элемент является элементом платформы или элементом содержимого платформы, проверьте, есть ли у этого элемента свойство Name. Если есть, скорее всего, это элемент платформы или элемент содержимого платформы. Чтобы убедиться в этом, обратитесь к разделу "Иерархия наследования" на странице типа элемента.
Чтобы включить целевые элементом платформы или элемента содержимого платформы в XAML, можно задать его Name свойство. В коде, необходимо также использовать RegisterName метод, чтобы зарегистрировать имя элемента в элементе, для которого вы создали NameScope.
В следующем примере, взятом из предыдущего примера, назначает имя MyRectangle
Rectangle, тип FrameworkElement.
<Rectangle Name="MyRectangle"
Width="100"
Height="100">
Rectangle myRectangle = new Rectangle();
myRectangle.Name = "MyRectangle";
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
this.RegisterName(myRectangle.Name, myRectangle);
После того как элемент получил имя, вы можете анимировать свойство этого элемента.
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="Width"
From="100" To="200" Duration="0:0:1" />
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation,
new PropertyPath(Rectangle.WidthProperty));
Freezable типы являются классы, наследующие от Freezable класса. Примеры Freezable включают SolidColorBrush, RotateTransform, и GradientStop.
Чтобы включить целевые Freezable с помощью анимации в XAML, использовании директива x: Name присвоить имя. В коде используйте RegisterName метод для регистрации имени элемента, для которого вы создали NameScope.
В следующем примере назначается имя, Freezable объекта.
<SolidColorBrush x:Name="MySolidColorBrush" Color="Blue" />
SolidColorBrush mySolidColorBrush = new SolidColorBrush(Colors.Blue);
this.RegisterName("MySolidColorBrush", mySolidColorBrush);
Затем этот объект можно выбрать в качестве целевого с помощью анимации.
<ColorAnimation
Storyboard.TargetName="MySolidColorBrush"
Storyboard.TargetProperty="Color"
From="Blue" To="Red" Duration="0:0:1" />
Storyboard.SetTargetName(myColorAnimation, "MySolidColorBrush");
Storyboard.SetTargetProperty(myColorAnimation,
new PropertyPath(SolidColorBrush.ColorProperty));
Storyboard объекты используются области видимости имен для разрешения TargetName свойство. Дополнительные сведения об областях видимости имен WPF см. в разделе Области видимости имен XAML в WPF. Если TargetName свойства указан, элемент, на котором она была определена, или, в случае стили, оформленного элемент целевым объектом для анимации.
Иногда имя не может быть назначен Freezable объекта. Например если Freezable объявлен как ресурс или используется для задания значения свойства в стиле, ему нельзя присвоить имя. Так как у объекта нет имени, к нему нельзя обратиться напрямую, но можно обратиться косвенно. В следующих разделах описано, как обращаться к целевым объектам косвенно.
Косвенное обращение
Иногда Freezable не может применяться непосредственно с помощью анимации, например, при Freezable объявлен как ресурс или используется для задания значения свойства в стиле. В таких случаях, несмотря на то, что вы не можете выбрать напрямую, можно анимировать Freezable объекта. Вместо того чтобы задавать TargetName свойство с именем Freezable, присвойте ему имя элемента, к которому Freezable «принадлежит». Например SolidColorBrush присваивается Fill прямоугольника элемент принадлежит этому прямоугольника. Чтобы анимировать кисть, необходимо установить анимации TargetProperty в цепи свойства, которое начинается с свойство элемента платформы или элемента содержимого платформы Freezable использовалась для установки и заканчивается Freezable анимируемое свойство.
<ColorAnimation
Storyboard.TargetName="Rectangle01"
Storyboard.TargetProperty="Fill.Color"
From="Blue" To="AliceBlue" Duration="0:0:1" />
DependencyProperty[] propertyChain =
new DependencyProperty[]
{Rectangle.FillProperty, SolidColorBrush.ColorProperty};
string thePath = "(0).(1)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myColorAnimation, myPropertyPath);
Обратите внимание, что, если Freezable является фиксированной, будет создан клон и этот клон будет анимироваться. Если это происходит, исходный объект HasAnimatedProperties свойство продолжает возвращать false
, так как исходный объект фактически не анимируется. Дополнительные сведения о клонировании см. в разделе Freezable Общие сведения об объектах.
Обратите внимание, что при косвенном обращении к целевым объектам можно обращаться к объектам, которых не существует. Например, можно предположить, что Background для конкретной кнопки было установлено с помощью SolidColorBrush и попробуете анимировать его свойство Color, когда на самом деле LinearGradientBrush использовалась для установки фона кнопки. В этих случаях исключение не вызывается; анимация не имеет видимого эффекта, так как LinearGradientBrush не реагирует на изменения в Color свойство.
В следующих разделах более подробно описан синтаксис косвенного обращения к целевым объектам.
Косвенное обращение к свойству объекта Freezable в XAML
Чтобы обратиться к свойству объекта freezable в XAML, используйте следующий синтаксис.
ElementPropertyName . FreezablePropertyName |
Where
ElementPropertyName свойство FrameworkElement которого Freezable используется для задания, и
FreezablePropertyName свойство Freezable для анимации.
Ниже показано, как анимировать Color из SolidColorBrush используемый для задания
Fill элемента прямоугольника.
<Rectangle
Name="Rectangle01"
Height="100"
Width="100"
Fill="{StaticResource MySolidColorBrushResource}">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetName="Rectangle01"
Storyboard.TargetProperty="Fill.Color"
From="Blue" To="AliceBlue" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Иногда требуется обратиться к объекту Freezable, который содержится в коллекции или массиве.
Чтобы обратиться к объекту Freezable, который содержится в коллекции, используйте следующий синтаксис пути.
ElementPropertyName .Children[ CollectionIndex ]. FreezablePropertyName |
Где CollectionIndex — индекс объекта в массиве или коллекции.
Например, предположим, что у прямоугольника есть TransformGroup ресурс, применяемый к его RenderTransform свойство и вы хотите анимировать одно из преобразований, он содержит.
<TransformGroup x:Key="MyTransformGroupResource"
x:Shared="False">
<ScaleTransform />
<RotateTransform />
</TransformGroup>
Ниже показано, как анимировать Angle свойство RotateTransform показано в предыдущем примере.
<Rectangle
Name="Rectangle02"
Height="100"
Width="100"
Fill="Blue"
RenderTransform="{StaticResource MyTransformGroupResource}">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Rectangle02"
Storyboard.TargetProperty="RenderTransform.Children[1].Angle"
From="0" To="360" Duration="0:0:1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Косвенное обращение к свойству объекта Freezable в коде
В коде создайте PropertyPath объекта. При создании PropertyPath, указать Path и PathParameters.
Чтобы создать PathParameters, необходимо создать массив типа DependencyProperty , содержащий список поля идентификаторов свойств зависимостей. — Первое поле идентификатора свойства FrameworkElement или FrameworkContentElement , Freezable используется для задания. Следующее поле идентификатора представляет свойство Freezable к целевому объекту. Представьте себе, как цепочку свойств, который подключается Freezable для FrameworkElement объекта.
Ниже приведен пример цепочки свойств зависимостей, предназначенное Color из SolidColorBrush присваивается Fill элемента прямоугольника.
DependencyProperty[] propertyChain =
new DependencyProperty[]
{Rectangle.FillProperty, SolidColorBrush.ColorProperty};
Необходимо также указать Path. Объект Path — String , сообщающий Path как интерпретировать его PathParameters. Для этого используется следующий синтаксис.
( OwnerPropertyArrayIndex ).( FreezablePropertyArrayIndex ) |
Where
OwnerPropertyArrayIndex — это индекс DependencyProperty массив, содержащий идентификатор FrameworkElement свойство объекта, Freezable используется для задания, и
FreezablePropertyArrayIndex — это индекс DependencyProperty массив, содержащий идентификатор свойства к целевому объекту.
В следующем примере показан Path , будет сопровождать PathParameters определенный в предыдущем примере.
DependencyProperty[] propertyChain =
new DependencyProperty[]
{Rectangle.FillProperty, SolidColorBrush.ColorProperty};
string thePath = "(0).(1)";
В следующем примере объединяются кода в предыдущих примерах для анимации Color из SolidColorBrush присваивается Fill элемента прямоугольника.
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
Rectangle rectangle01 = new Rectangle();
rectangle01.Name = "Rectangle01";
this.RegisterName(rectangle01.Name, rectangle01);
rectangle01.Width = 100;
rectangle01.Height = 100;
rectangle01.Fill =
(SolidColorBrush)this.Resources["MySolidColorBrushResource"];
ColorAnimation myColorAnimation = new ColorAnimation();
myColorAnimation.From = Colors.Blue;
myColorAnimation.To = Colors.AliceBlue;
myColorAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myColorAnimation, rectangle01.Name);
DependencyProperty[] propertyChain =
new DependencyProperty[]
{Rectangle.FillProperty, SolidColorBrush.ColorProperty};
string thePath = "(0).(1)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myColorAnimation, myPropertyPath);
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myColorAnimation);
BeginStoryboard myBeginStoryboard = new BeginStoryboard();
myBeginStoryboard.Storyboard = myStoryboard;
EventTrigger myMouseEnterTrigger = new EventTrigger();
myMouseEnterTrigger.RoutedEvent = Rectangle.MouseEnterEvent;
myMouseEnterTrigger.Actions.Add(myBeginStoryboard);
rectangle01.Triggers.Add(myMouseEnterTrigger);
Иногда требуется обратиться к объекту Freezable, который содержится в коллекции или массиве. Например, предположим, что у прямоугольника есть TransformGroup ресурс, применяемый к его RenderTransform свойство и вы хотите анимировать одно из преобразований, он содержит.
<TransformGroup x:Key="MyTransformGroupResource"
x:Shared="False">
<ScaleTransform />
<RotateTransform />
</TransformGroup>
Целевой объект Freezable содержится в коллекции, используйте следующий синтаксис пути.
( OwnerPropertyArrayIndex ).( CollectionChildrenPropertyArrayIndex ) [ CollectionIndex ].( FreezablePropertyArrayIndex ) |
Где CollectionIndex — индекс объекта в массиве или коллекции.
Целевой объект Angle свойство RotateTransform, во втором преобразовании в TransformGroup, следует ввести следующую Path и PathParameters.
DependencyProperty[] propertyChain =
new DependencyProperty[]
{
Rectangle.RenderTransformProperty,
TransformGroup.ChildrenProperty,
RotateTransform.AngleProperty
};
string thePath = "(0).(1)[1].(2)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myDoubleAnimation, myPropertyPath);
В примере показан полный код для анимации Angle из RotateTransform внутри TransformGroup.
Rectangle rectangle02 = new Rectangle();
rectangle02.Name = "Rectangle02";
this.RegisterName(rectangle02.Name, rectangle02);
rectangle02.Width = 100;
rectangle02.Height = 100;
rectangle02.Fill = Brushes.Blue;
rectangle02.RenderTransform =
(TransformGroup)this.Resources["MyTransformGroupResource"];
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 0;
myDoubleAnimation.To = 360;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myDoubleAnimation, rectangle02.Name);
DependencyProperty[] propertyChain =
new DependencyProperty[]
{
Rectangle.RenderTransformProperty,
TransformGroup.ChildrenProperty,
RotateTransform.AngleProperty
};
string thePath = "(0).(1)[1].(2)";
PropertyPath myPropertyPath = new PropertyPath(thePath, propertyChain);
Storyboard.SetTargetProperty(myDoubleAnimation, myPropertyPath);
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
BeginStoryboard myBeginStoryboard = new BeginStoryboard();
myBeginStoryboard.Storyboard = myStoryboard;
EventTrigger myMouseEnterTrigger = new EventTrigger();
myMouseEnterTrigger.RoutedEvent = Rectangle.MouseEnterEvent;
myMouseEnterTrigger.Actions.Add(myBeginStoryboard);
rectangle02.Triggers.Add(myMouseEnterTrigger);
Косвенное обращение с использованием объекта Freezable в качестве начальной точки
Предыдущих разделах мы описали косвенное обращение к Freezable , начав с FrameworkElement или FrameworkContentElement и создав цепочку свойств до Freezable подчиненных свойств. Можно также использовать Freezable качестве отправной точки и косвенно обращаться к одному из его Freezable подсвойства. Одно дополнительное ограничение применяется при использовании Freezable отправной точки для косвенного: начальный Freezable и каждый Freezable не должны фиксироваться между ним и косвенно целевых подчиненных свойств.
Интерактивное управление раскадровкой в XAML
Чтобы запустить раскадровку XAML, использовании BeginStoryboard запуска действия. BeginStoryboard распределяет анимации объектов и свойств и запускает раскадровку. (Дополнительные сведения об этом процессе см. в разделе анимации и общие сведения о характере системы.) Если вы предоставите BeginStoryboard имя, указав его Name свойство, можно упростить управляемой раскадровки. Вы можете затем интерактивно управлять раскадровкой после ее запуска. Ниже приведен список действий для управляемой раскадровки, которые используются совместно с триггерами событий для управления раскадровкой.
PauseStoryboard: Приостанавливает раскадровку.
ResumeStoryboard: Возобновляет приостановленную раскадровку.
SetStoryboardSpeedRatio: Изменяет скорость раскадровки.
SkipStoryboardToFill: Перемещает раскадровку в конец ее периода заполнения, если он имеется.
StopStoryboard: Останавливает раскадровку.
RemoveStoryboard: Удаляет раскадровку.
В следующем примере показано использование действий для интерактивного управления раскадровкой.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Microsoft.SDK.Animation.ControllableStoryboardExample"
WindowTitle="Fading Rectangle Example">
<StackPanel Margin="10">
<Rectangle
Name="MyRectangle"
Width="100"
Height="100"
Fill="Blue">
</Rectangle>
<Button Name="BeginButton">Begin</Button>
<Button Name="PauseButton">Pause</Button>
<Button Name="ResumeButton">Resume</Button>
<Button Name="SkipToFillButton">Skip To Fill</Button>
<Button Name="StopButton">Stop</Button>
<StackPanel.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="BeginButton">
<BeginStoryboard Name="MyBeginStoryboard">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="(Rectangle.Opacity)"
From="1.0" To="0.0" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="PauseButton">
<PauseStoryboard BeginStoryboardName="MyBeginStoryboard" />
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="ResumeButton">
<ResumeStoryboard BeginStoryboardName="MyBeginStoryboard" />
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="SkipToFillButton">
<SkipStoryboardToFill BeginStoryboardName="MyBeginStoryboard" />
</EventTrigger>
<EventTrigger RoutedEvent="Button.Click" SourceName="StopButton">
<StopStoryboard BeginStoryboardName="MyBeginStoryboard" />
</EventTrigger>
</StackPanel.Triggers>
</StackPanel>
</Page>
Интерактивное управление раскадровкой с помощью кода
В предыдущих примерах было показано, как анимировать свойства с помощью действий триггера. В коде, можно также управлять раскадровкой с помощью интерактивных методов класса Storyboard класса. Для Storyboard чтобы сделать интерактивными в коде, необходимо использовать соответствующую перегрузку раскадровки Begin метод и указать true
чтобы сделать раскадровку управляемой. См. в разделе Begin(FrameworkElement, Boolean) дополнительную информацию.
В следующем списке приведены методы, которые можно использовать для управления Storyboard после ее запуска:
С помощью этих методов удобен тем, что не нужно создавать Trigger или TriggerAction объектов; нужна ссылка на управляемый Storyboard требуется работать.
Примечание. Все интерактивные действия, выполняемые Clockи поэтому на Storyboard произойдет при следующем такте, который произойдет незадолго перед следующей операцией рендеринга. Например, если вы используете Seek метод для перехода к следующей точке анимации, значение свойства не изменится сразу же, вместо этого изменяется значение при следующем такте.
Приведенный ниже показано, как применять анимации с помощью интерактивных методов класса и управлять Storyboard класса.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace SDKSample
{
public class ControllableStoryboardExample : Page
{
private Storyboard myStoryboard;
public ControllableStoryboardExample()
{
// Create a name scope for the page.
NameScope.SetNameScope(this, new NameScope());
this.WindowTitle = "Controllable Storyboard Example";
StackPanel myStackPanel = new StackPanel();
myStackPanel.Margin = new Thickness(10);
// Create a rectangle.
Rectangle myRectangle = new Rectangle();
myRectangle.Name = "myRectangle";
// Assign the rectangle a name by
// registering it with the page, so that
// it can be targeted by storyboard
// animations.
this.RegisterName(myRectangle.Name, myRectangle);
myRectangle.Width = 100;
myRectangle.Height = 100;
myRectangle.Fill = Brushes.Blue;
myStackPanel.Children.Add(myRectangle);
//
// Create an animation and a storyboard to animate the
// rectangle.
//
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 1.0;
myDoubleAnimation.To = 0.0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(5000));
myDoubleAnimation.AutoReverse = true;
// Create the storyboard.
myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.OpacityProperty));
//
// Create some buttons to control the storyboard
// and a panel to contain them.
//
StackPanel buttonPanel = new StackPanel();
buttonPanel.Orientation = Orientation.Horizontal;
Button beginButton = new Button();
beginButton.Content = "Begin";
beginButton.Click += new RoutedEventHandler(beginButton_Clicked);
buttonPanel.Children.Add(beginButton);
Button pauseButton = new Button();
pauseButton.Content = "Pause";
pauseButton.Click += new RoutedEventHandler(pauseButton_Clicked);
buttonPanel.Children.Add(pauseButton);
Button resumeButton = new Button();
resumeButton.Content = "Resume";
resumeButton.Click += new RoutedEventHandler(resumeButton_Clicked);
buttonPanel.Children.Add(resumeButton);
Button skipToFillButton = new Button();
skipToFillButton.Content = "Skip to Fill";
skipToFillButton.Click += new RoutedEventHandler(skipToFillButton_Clicked);
buttonPanel.Children.Add(skipToFillButton);
Button setSpeedRatioButton = new Button();
setSpeedRatioButton.Content = "Triple Speed";
setSpeedRatioButton.Click += new RoutedEventHandler(setSpeedRatioButton_Clicked);
buttonPanel.Children.Add(setSpeedRatioButton);
Button stopButton = new Button();
stopButton.Content = "Stop";
stopButton.Click += new RoutedEventHandler(stopButton_Clicked);
buttonPanel.Children.Add(stopButton);
myStackPanel.Children.Add(buttonPanel);
this.Content = myStackPanel;
}
// Begins the storyboard.
private void beginButton_Clicked(object sender, RoutedEventArgs args)
{
// Specifying "true" as the second Begin parameter
// makes this storyboard controllable.
myStoryboard.Begin(this, true);
}
// Pauses the storyboard.
private void pauseButton_Clicked(object sender, RoutedEventArgs args)
{
myStoryboard.Pause(this);
}
// Resumes the storyboard.
private void resumeButton_Clicked(object sender, RoutedEventArgs args)
{
myStoryboard.Resume(this);
}
// Advances the storyboard to its fill period.
private void skipToFillButton_Clicked(object sender, RoutedEventArgs args)
{
myStoryboard.SkipToFill(this);
}
// Updates the storyboard's speed.
private void setSpeedRatioButton_Clicked(object sender, RoutedEventArgs args)
{
// Makes the storyboard progress three times as fast as normal.
myStoryboard.SetSpeedRatio(this, 3);
}
// Stops the storyboard.
private void stopButton_Clicked(object sender, RoutedEventArgs args)
{
myStoryboard.Stop(this);
}
}
}
Анимация с использованием стилей
Можно использовать Storyboard объектов для определения анимаций в Style. Анимации с помощью Storyboard в Style похоже на использование Storyboard в другом месте, со следующими тремя исключениями:
Вы не укажете TargetName; Storyboard всегда указывает элемент, к которому Style применяется. Целевой объект Freezable объекты, следует использовать косвенное обращение. Дополнительные сведения о косвенном обращении см. в разделе косвенное обращение раздел.
Нельзя указать SourceName для EventTrigger или Trigger.
Нельзя использовать динамический ресурс ссылки или выражения привязки данных для задания Storyboard или значений свойств анимации. Это потому, что весь код внутри Style должен быть поточно ориентированными, и система управления должна FreezeStoryboard объектов, чтобы сделать их потокобезопасными. Объект Storyboard нельзя зафиксировать, если его или ее дочерние временные шкалы содержат динамические ресурсы ссылки или выражения привязки данных. Дополнительные сведения о фиксации и других Freezable функции, см. в разделе Freezable Общие сведения об объектах.
В XAML, нельзя объявлять обработчики событий для Storyboard или событий анимации.
Пример, показывающий, как определить раскадровку в стиле, см. в разделе анимация с использованием стилей пример.
Анимация в ControlTemplate
Можно использовать Storyboard объектов для определения анимаций в ControlTemplate. Анимации с помощью Storyboard в ControlTemplate похоже на использование Storyboard в другом месте, со следующими двумя исключениями:
TargetName Могут ссылаться только на дочерние объекты ControlTemplate. Если TargetName не указан, элемент, в который целевым объектом для анимации ControlTemplate применяется.
SourceName Для EventTrigger или Trigger могут ссылаться только на дочерние объекты ControlTemplate.
Нельзя использовать динамический ресурс ссылки или выражения привязки данных для задания Storyboard или значений свойств анимации. Это потому, что весь код внутри ControlTemplate должен быть поточно ориентированными, и система управления должна FreezeStoryboard объектов, чтобы сделать их потокобезопасными. Объект Storyboard нельзя зафиксировать, если его или ее дочерние временные шкалы содержат динамические ресурсы ссылки или выражения привязки данных. Дополнительные сведения о фиксации и других Freezable функции, см. в разделе Freezable Общие сведения об объектах.
В XAML, нельзя объявлять обработчики событий для Storyboard или событий анимации.
Пример, показывающий, как определить раскадровку в ControlTemplate, см. в разделе анимация в ControlTemplate пример.
Анимация при изменении значения свойства
В стилях и шаблонах элементов можно использовать объекты триггеров для запуска раскадровки при изменении свойства. Примеры, см. в разделе триггер анимации при изменении значения свойства и анимация в ControlTemplate.
Анимации с помощью свойства Trigger объекты ведут себя в сложнее, чем EventTrigger анимации или анимации к использованию Storyboard методы. Они «переходной» с анимацией определены другими Trigger объектов, но compose с EventTrigger и анимациями, запускаемыми.