动画概述
更新:2010 年 10 月
Windows Presentation Foundation (WPF) 提供了一组强大的图形和布局功能,通过应用这些功能,可以创建漂亮的用户界面和吸引人的文档。 动画不仅可以使漂亮的用户界面更加引人注目,还可以使其更加便于使用。 只需对背景色进行动画处理或应用动画 Transform,就可以创造出生动的屏幕过渡效果或提供有帮助的视觉提示。
本概述介绍了 WPF 动画和计时系统, 并使用演示图板重点讨论 WPF 对象的动画。
本主题包括下列各节。
- 动画简介
- WPF 属性动画系统
- 示例:使元素逐渐进入视野并从视野中逐渐消失
- 动画类型
- 对属性应用动画
- 以交互方式控制演示图板
- 动画结束后会发生什么情况?
- 对动画进行数据绑定和动画处理
- 其他动画处理方式
- 动画示例
- 相关主题
- 参考
动画简介
动画是快速播放一系列图像(其中每个图像与下一个图像略微不同)给人造成的一种幻觉。 大脑感觉这组图像是一个变化的场景。 在电影中,摄像机每秒钟拍摄许多照片(帧),便可使人形成这种幻觉。 用投影仪播放这些帧时,观众便可以看电影了。
计算机上的动画与此类似。 例如,使一个矩形逐渐从视野中消失的程序可能按以下方式工作。
程序创建一个计时器。
程序按照设置的时间间隔检查计时器以查看经历了多长时间。
程序每次检查计时器时,它将根据经历的时间来计算矩形的当前不透明度值。
然后程序用新值更新矩形并重画此矩形。
在 WPF 出现之前,Microsoft Windows 开发人员必须创建和管理自己的计时系统或使用特殊的自定义库。 WPF 包括一个通过托管代码和Extensible Application Markup Language (XAML) 公开的高效计时系统,该系统紧密地集成到 WPF 框架中。通过使用 WPF 动画,可以轻松地对控件和其他图形对象进行动画处理。
WPF 可以高效地处理管理计时系统和重绘屏幕的所有后台事务。 它提供了计时类,使用这些类,可以重点关注要创造的效果,而非实现这些效果的机制。 此外,WPF 通过公开动画基类(您的类可以继承自这些类)让您可以轻松创建自己的动画,这样便可以制作自定义动画。 这些自定义的动画获得了标准动画类的许多性能优点。
WPF 属性动画系统
如果了解关于计时系统的一些重要概念,则在使用 WPF 时可能会更加轻松一些。 最重要的是,在 WPF 中,通过对对象的个别属性应用动画,可以对对象进行动画处理。 例如,若要使框架元素增大,请对其 Width 和 Height 属性进行动画处理。 若要使对象逐渐从视野中消失,可以对其 Opacity 属性进行动画处理。
要使属性具有动画功能,属性必须满足以下三个要求:
它必须是依赖项属性。
它必须属于继承自 DependencyObject 并实现 IAnimatable 接口的类。
必须存在可用的兼容动画类型。 (如果 WPF 未提供可用的兼容动画类型,则可以创建您自己的兼容动画类型。 请参见自定义动画概述。)
WPF 包含许多具有 IAnimatable 属性的对象。 诸如 Button、TabControl 和 Panel 控件以及 Shape 对象都继承自 DependencyObject。 它们的大多数属性都是依赖项属性。
您几乎可以在任何地方使用动画,包括在样式和控件模板中使用。 动画未必可见;对于不属于用户界面的对象,如果它们满足本节中所述的条件,便可以对其进行动画处理。
示例:使元素逐渐进入视野并从视野中逐渐消失
此示例演示如何使用 WPF 动画对依赖项属性的值进行动画处理。 本示例使用 DoubleAnimation(一种生成 Double 值的动画类型)对 Rectangle 的 Opacity 属性进行动画处理。 因此,Rectangle 将逐渐进入视野并逐渐从视野中消失。
示例的第一部分创建一个 Rectangle 元素。 下面的步骤表明如何创建动画并将其应用于矩形的 Opacity 属性。
下面的示例演示在 XAML 中,如何在 StackPanel 中创建 Rectangle 元素。
<StackPanel Margin="10">
<Rectangle
Name="MyRectangle"
Width="100"
Height="100"
Fill="Blue">
</Rectangle>
</StackPanel>
下面的示例演示在代码中,如何在 StackPanel 中创建 Rectangle 元素。
Dim myPanel As StackPanel = New StackPanel
myPanel.Margin = New Thickness(10)
Dim myRectangle As Rectangle = New Rectangle
myRectangle.Name = "myRectangle"
Me.RegisterName(myRectangle.Name, myRectangle)
myRectangle.Width = 100
myRectangle.Height = 100
myRectangle.Fill = Brushes.Blue
myPanel.Children.Add(myRectangle)
Me.Content = myPanel
StackPanel myPanel = new StackPanel();
myPanel.Margin = new Thickness(10);
Rectangle myRectangle = new Rectangle();
myRectangle.Name = "myRectangle";
this.RegisterName(myRectangle.Name, myRectangle);
myRectangle.Width = 100;
myRectangle.Height = 100;
myRectangle.Fill = Brushes.Blue;
myPanel.Children.Add(myRectangle);
this.Content = myPanel;
第 1 部分:创建 DoubleAnimation
使元素逐渐进入视野并逐渐从视野中消失的一种方法是对其 Opacity 属性进行动画处理。 由于 Opacity 属性的类型是 Double,因此需要一个产生双精度值的动画。 DoubleAnimation 就是这样的一个动画。 DoubleAnimation 创建两个双精度值之间的过渡。 若要指定其起始值,可设置其 From 属性。 若要指定其终止值,可设置其 To 属性。
不透明度值 1.0 使对象完全不透明,不透明度值 0.0 使对象完全不可见。 若要使动画的不透明度值从 1.0 过渡为 0.0,可以将其 From 属性设置为 1.0,将其 To 属性设置为 0.0。 下面的示例演示如何在 XAML 中创建 DoubleAnimation。
<DoubleAnimation From="1.0" To="0.0" />
下面的示例演示如何在代码中创建 DoubleAnimation。
Dim myDoubleAnimation As DoubleAnimation = New DoubleAnimation() myDoubleAnimation.From = 1.0 myDoubleAnimation.To = 0.0
DoubleAnimation myDoubleAnimation = new DoubleAnimation(); myDoubleAnimation.From = 1.0; myDoubleAnimation.To = 0.0;
然后,必须指定 Duration。 动画的 Duration 指定了从其起始值过渡为目标值所需的时间。 下面的内容演示如何在 XAML 中将 Duration 设置为五秒。
<DoubleAnimation From="1.0" To="0.0" Duration="0:0:5" />
下面的内容演示如何在代码中将 Duration 设置为五秒。
myDoubleAnimation.Duration = New Duration(TimeSpan.FromSeconds(5))
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));
上面的代码显示了不透明度值从 1.0 向 0.0 转换的动画,此转换使目标元素从完全不透明逐渐转变为完全不可见。 若要使元素在消失后再逐渐回到视野中,请将动画的 AutoReverse 属性设置为 true。 若要使动画无限期地重复,请将其 RepeatBehavior 属性设置为 Forever。下面的内容演示如何在 XAML 中设置 AutoReverse 和 RepeatBehavior 属性。
<DoubleAnimation From="1.0" To="0.0" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever"/>
下面的内容演示如何在代码中设置 AutoReverse 和 RepeatBehavior 属性。
myDoubleAnimation.AutoReverse = True myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever
myDoubleAnimation.AutoReverse = true; myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
第 2 部分:创建演示图板
若要向对象应用动画,请创建 Storyboard 并使用 TargetName 和 TargetProperty 附加属性指定要进行动画处理的对象和属性。
创建 Storyboard 并将动画添加为其子项。 下面的示例演示如何在 XAML 中创建 Storyboard。
若要在代码中创建 Storyboard,请在类级别声明 Storyboard 变量。
Class MainWindow Private myStoryboard As Storyboard
public partial class MainWindow : Window { private Storyboard myStoryboard;
然后初始化 Storyboard 并将动画添加为其子项。
myStoryboard = New Storyboard() myStoryboard.Children.Add(myDoubleAnimation)
myStoryboard = new Storyboard(); myStoryboard.Children.Add(myDoubleAnimation);
Storyboard 必须知道要在哪里应用动画。 使用 Storyboard.TargetName 附加属性指定要进行动画处理的对象。 下面的内容演示如何在 XAML 中将 DoubleAnimation 的目标名称设置为 MyRectangle。
<Storyboard> <DoubleAnimation Storyboard.TargetName="MyRectangle" From="1.0" To="0.0" Duration="0:0:1" AutoReverse="True" RepeatBehavior="Forever" /> </Storyboard>
下面的内容演示如何在代码中将 DoubleAnimation 的目标名称设置为 MyRectangle。
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name)
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
使用 TargetProperty 附加属性指定要进行动画处理的属性。 下面的内容演示如何在 XAML 中将动画配置为面向 Rectangle 的 Opacity 属性。
<Storyboard> <DoubleAnimation Storyboard.TargetName="MyRectangle" Storyboard.TargetProperty="Opacity" From="1.0" To="0.0" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever" /> </Storyboard>
下面的内容演示如何在代码中将动画配置为面向 Rectangle 的 Opacity 属性。
Storyboard.SetTargetProperty(myDoubleAnimation, New PropertyPath(Rectangle.OpacityProperty))
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.OpacityProperty));
有关 TargetProperty 语法的更多信息以及其他示例,请参见演示图板概述。
第 3 部分 (XAML):将演示图板与触发器关联
在 XAML 中应用和启动 Storyboard 的最简单的方法是使用事件触发器。 本节演示如何在 XAML 中将 Storyboard 与触发器关联。
创建一个 BeginStoryboard 对象并将演示图板与其关联。 BeginStoryboard 是一种应用和启动 Storyboard 的 TriggerAction。
<BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="MyRectangle" Storyboard.TargetProperty="Opacity" From="1.0" To="0.0" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever" /> </Storyboard> </BeginStoryboard>
创建 EventTrigger 并将 BeginStoryboard 添加至其 Actions 集合。 将 EventTrigger 的 RoutedEvent 属性设置为启动 Storyboard 所需的路由事件。 (有关路由事件的更多信息,请参见路由事件概述。)
<!-- Animates the rectangle's opacity. --> <EventTrigger RoutedEvent="Rectangle.Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="MyRectangle" Storyboard.TargetProperty="Opacity" From="1.0" To="0.0" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever" /> </Storyboard> </BeginStoryboard> </EventTrigger>
将 EventTrigger 添加至矩形的 Triggers 集合。
<Rectangle Name="MyRectangle" Width="100" Height="100" Fill="Blue"> <Rectangle.Triggers> <!-- Animates the rectangle's opacity. --> <EventTrigger RoutedEvent="Rectangle.Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="MyRectangle" Storyboard.TargetProperty="Opacity" From="1.0" To="0.0" Duration="0:0:5" AutoReverse="True" RepeatBehavior="Forever" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Rectangle.Triggers> </Rectangle>
第 3 部分(代码):将演示图板与事件处理程序关联
在代码中应用和启动 Storyboard 的最简单的方法是使用事件处理程序。 本节演示如何在代码中将 Storyboard 与事件处理程序关联。
注册矩形的 Loaded 事件。
AddHandler myRectangle.Loaded, AddressOf myRectangleLoaded
myRectangle.Loaded += new RoutedEventHandler(myRectangleLoaded);
声明事件处理程序。 在事件处理程序中,使用 Begin 方法来应用演示图板。
Private Sub myRectangleLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs) myStoryboard.Begin(Me) End Sub
private void myRectangleLoaded(object sender, RoutedEventArgs e) { myStoryboard.Begin(this); }
完整的示例
下面的内容演示如何在 XAML 中创建逐渐进入视野并从视野中逐渐消失的矩形。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel Margin="10">
<Rectangle
Name="MyRectangle"
Width="100"
Height="100"
Fill="Blue">
<Rectangle.Triggers>
<!-- Animates the rectangle's opacity. -->
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0.0" Duration="0:0:5"
AutoReverse="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</StackPanel>
</Grid>
</Window>
下面的内容演示如何在代码中创建逐渐进入视野并从视野中逐渐消失的矩形。
Imports System.Windows.Media.Animation
Class MainWindow
Private myStoryboard As Storyboard
Public Sub New()
InitializeComponent()
Dim myPanel As New StackPanel()
myPanel.Margin = New Thickness(10)
Dim myRectangle As New Rectangle()
myRectangle.Name = "myRectangle"
Me.RegisterName(myRectangle.Name, myRectangle)
myRectangle.Width = 100
myRectangle.Height = 100
myRectangle.Fill = Brushes.Blue
Dim myDoubleAnimation As New DoubleAnimation()
myDoubleAnimation.From = 1.0
myDoubleAnimation.To = 0.0
myDoubleAnimation.Duration = New Duration(TimeSpan.FromSeconds(5))
myDoubleAnimation.AutoReverse = True
myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever
myStoryboard = New Storyboard()
myStoryboard.Children.Add(myDoubleAnimation)
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name)
Storyboard.SetTargetProperty(myDoubleAnimation, New PropertyPath(Rectangle.OpacityProperty))
' Use the Loaded event to start the Storyboard.
AddHandler myRectangle.Loaded, AddressOf myRectangleLoaded
myPanel.Children.Add(myRectangle)
Me.Content = myPanel
End Sub
Private Sub myRectangleLoaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
myStoryboard.Begin(Me)
End Sub
End Class
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
private Storyboard myStoryboard;
public MainWindow()
{
InitializeComponent();
StackPanel myPanel = new StackPanel();
myPanel.Margin = new Thickness(10);
Rectangle myRectangle = new Rectangle();
myRectangle.Name = "myRectangle";
this.RegisterName(myRectangle.Name, myRectangle);
myRectangle.Width = 100;
myRectangle.Height = 100;
myRectangle.Fill = Brushes.Blue;
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 1.0;
myDoubleAnimation.To = 0.0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));
myDoubleAnimation.AutoReverse = true;
myDoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.OpacityProperty));
// Use the Loaded event to start the Storyboard.
myRectangle.Loaded += new RoutedEventHandler(myRectangleLoaded);
myPanel.Children.Add(myRectangle);
this.Content = myPanel;
}
private void myRectangleLoaded(object sender, RoutedEventArgs e)
{
myStoryboard.Begin(this);
}
}
}
动画类型
由于动画生成属性值,因此对于不同的属性类型,会有不同的动画类型。 若要对采用 Double 的属性(例如元素的 Width 属性)进行动画处理,请使用生成 Double 值的动画。 若要对采用 Point 的属性进行动画处理,请使用生成 Point 值的动画,依此类推。 由于存在许多不同的属性类型,因此 System.Windows.Media.Animation 命名空间中存在一些动画类。 幸好它们都遵循严格的命名约定,因此可以轻松地区分它们:
<类型>Animation
这些动画称为“From/To/By”或“基本”动画,它们在起始值和目标值之间进行动画处理,或者通过将偏移量值与其起始值相加来进行动画处理。
若要指定起始值,请设置动画的“From”属性。
若要指定终止值,请设置动画的“To”属性。
若要指定偏移量值,请设置动画的“By”属性。
此概述中的示例使用这些动画,因为这些动画使用起来最简单。 From/To/By 动画概述中详细描述了“From/To/By”动画。
<类型>AnimationUsingKeyFrames
关键帧动画的功能比“From/To/By”动画的功能更强大,因为您可以指定任意多个目标值,甚至可以控制它们的插值方法。 某些类型的内容只能用关键帧动画进行动画处理。 关键帧动画概述中详细描述了关键帧动画。
<类型>AnimationUsingPath
路径动画使您能够使用几何路径来生成动画值。
<类型>AnimationBase
在实现时对 <类型> 值进行动画处理的抽象类。 此类用作 <类型>Animation 和 <类型>AnimationUsingKeyFrames 类的基类。 只有在想要创建自己的自定义动画时,才必须直接处理这些类。 否则,请使用 <类型>Animation 或 KeyFrame<类型>Animation。
在大多数情况下,您将需要使用 <类型>Animation 类,例如 DoubleAnimation 和 ColorAnimation。
下表显示了一些常用动画类型以及与这些类型一起使用的一些属性。
属性类型 |
对应的基本 (From/To/By) 动画 |
对应的关键帧动画 |
对应的路径动画 |
用法示例 |
---|---|---|---|---|
无 |
对 SolidColorBrush 或 GradientStop 的 Color 进行动画处理。 |
|||
对 EllipseGeometry 的 Center 位置进行动画处理。 |
||||
无 |
无 |
动画是时间线
所有动画类型均继承自 Timeline 类,因此所有动画都是专用类型的时间线。 Timeline 定义时间段。 您可以指定时间线的以下计时行为:其 Duration 和重复次数,甚至可以为时间线指定时间走得多快。
因为动画是 Timeline,所以它还表示一个时间段。 在动画的指定时间段(即 Duration)内运行动画时,动画还会计算输出值。 在运行或“播放”动画时,动画将更新与其关联的属性。
Duration、AutoReverse 和 RepeatBehavior 是三个常用的计时属性。
Duration 属性
如前文所述,时间线代表一个时间段。 该时间段的长度由时间线的 Duration(通常用 TimeSpan 值来指定)来决定。 当时间线达到其持续时间的终点时,表示时间线完成了一次重复。
动画使用其 Duration 属性来确定其当前值。 如果没有为动画指定 Duration 值,它将使用默认值(1 秒)。
下面的语法显示了 Duration 属性的Extensible Application Markup Language (XAML) 特性语法的简化版本。
小时:分钟:秒 |
下表显示了一些 Duration 设置及其结果值。
设置 |
所得值 |
---|---|
0:0:5.5 |
5.5 秒。 |
0:30:5.5 |
30 分 5.5 秒。 |
1:30:5.5 |
1 小时 30 分 5.5 秒。 |
在代码中指定 Duration 的一种方法是使用 FromSeconds 方法创建 TimeSpan,然后使用该 TimeSpan 声明新的 Duration 结构。
有关 Duration 值和完整的Extensible Application Markup Language (XAML) 语法的更多信息,请参加 Duration 结构。
AutoReverse
AutoReverse 属性指定时间线在到达其 Duration 的终点后是否倒退。 如果将此动画属性设置为 true,则动画在到达其 Duration 的终点后将倒退,即从其终止值向其起始值反向播放。 默认情况下,该属性为 false。
RepeatBehavior
RepeatBehavior 属性指定时间线的播放次数。 默认情况下,时间线的重复次数为 1.0,即播放一次时间线,根本不进行重复。
有关这些属性和其他属性的更多信息,请参见计时行为概述。
对属性应用动画
前面几节描述动画的不同类型及其计时属性。 本节演示如何对要进行动画处理的属性应用动画。 Storyboard 对象提供了对属性应用动画的一种方法。 Storyboard 是一个为其所包含的动画提供目标信息的容器时间线。
以对象和属性为目标
Storyboard 类提供 TargetName 和 TargetProperty 附加属性。 通过在动画上设置这些属性,您将告诉动画对哪些内容进行动画处理。 但是,通常必须为对象提供一个名称,动画才能以该对象作为处理目标。
为 FrameworkElement 分配名称不同于为 Freezable 对象分配名称。 大多数控件和面板是框架元素;而大多数纯图形对象(如画笔、转换和几何图形)是可冻结的对象。 如果不确定类型是 FrameworkElement 还是 Freezable,请参阅其参考文档的“继承层次结构”部分。
若要使 FrameworkElement 成为动画目标,应通过设置其 Name 属性为其提供一个名称。 在代码中,还必须使用 RegisterName 方法向元素名称所属的页面注册该元素名称。
若要使 Freezable 对象成为 XAML 中的动画目标,应使用 x:Name 指令为其分配一个名称。 在代码中,只需使用 RegisterName 方法向对象所属的页面注册该对象。
下面几节举例说明如何使用 XAML 和代码为元素命名。 有关命名和设定目标的更多详细信息,请参见演示图板概述。
应用和启动演示图板
若要使用 XAML 启动演示图板,应将其与 EventTrigger 关联。 EventTrigger 是一个描述在发生指定事件时执行哪些操作的对象。 这些操作中的一个操作可以是 BeginStoryboard 操作,您可以使用此操作启动演示图板。 事件触发器与事件处理程序的概念类似,因为通过使用它们,您都可以指定应用程序如何响应特定事件。 与事件处理程序不同的是,您完全可以使用 XAML 来描述事件触发器,而无需使用其他代码。
若要使用代码启动 Storyboard,您可以使用 EventTrigger 或使用 Storyboard 类的 Begin 方法。
以交互方式控制演示图板
前面的示例演示如何在事件发生时启动 Storyboard。 您也可以在 Storyboard 启动后以交互方式控制它:可以暂停、继续和停止它,并可以使其进入到其填充期,还可以查找和移除 Storyboard。 有关更多信息以及演示如何以交互方式控制 Storyboard 的示例,请参见演示图板概述。
动画结束后会发生什么情况?
FillBehavior 属性指定时间线结束时的行为方式。 默认情况下,时间线结束时将启动 Filling。 处于 Filling 状态动画将保持其最终输出值。
前面示例中的 DoubleAnimation 不会终止,因为它的 RepeatBehavior 属性设置为 Forever。 下面的示例使用类似的动画对矩形进行动画处理。 与前面的示例不同,此动画的 RepeatBehavior 和 AutoReverse 属性设为默认值。 因此,动画运行五秒钟使其不透明度值从 1 转变成 0,然后停止。
<Rectangle
Name="MyRectangle"
Width="100"
Height="100"
Fill="Blue">
<Rectangle.Triggers>
<!-- Animates the rectangle's opacity. -->
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="MyRectangle"
Storyboard.TargetProperty="Opacity"
From="1.0" To="0" Duration="0:0:5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
Dim myDoubleAnimation As New DoubleAnimation()
myDoubleAnimation.From = 1.0
myDoubleAnimation.To = 0.0
myDoubleAnimation.Duration = New Duration(TimeSpan.FromSeconds(5))
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 1.0;
myDoubleAnimation.To = 0.0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(5));
因为动画的 FillBehavior 未发生变化,仍然为其默认值 HoldEnd,所以当动画结束时动画将保持其最终值 0。 因此,在动画结束后,矩形的 Opacity 仍然为 0。 如果将矩形的 Opacity 设置为另一个值,则您的代码似乎无效,因为动画仍将影响 Opacity 属性。
在代码中重新获得对动画属性的控制的一种方法是使用 BeginAnimation 方法,并将 AnimationTimeline 参数指定为 null。 有关更多信息及示例,请参见如何:在使用演示图板对属性进行动画处理后设置该属性。
请注意,虽然设置一个具有 Active 或 Filling 动画的属性值好像不起作用,但属性值确实发生了变化。 有关更多信息,请参见 动画和计时系统概述。
对动画进行数据绑定和动画处理
您可以对大多数动画属性绑定数据或进行动画处理;例如,可以对 DoubleAnimation 的 Duration 属性进行动画处理。 但是,由于计时系统工作方式的缘故,绑定有数据或进行过动画处理的动画的行为与其他绑定有数据或进行过动画处理的对象的行为不同。 若要了解它们的行为,请了解对属性应用动画的意义,这将十分有用。
请参见上节中演示如何对矩形的 Opacity 进行动画处理的示例。 加载前面示例中的矩形时,它的事件触发器将应用 Storyboard。 计时系统会创建 Storyboard 及其动画的副本。 系统将冻结这些副本(使它们成为只读副本),并且将根据它们来创建 Clock 对象。 这些时钟将执行对目标属性进行动画处理的实际工作。
计时系统为 DoubleAnimation 创建一个时钟,并将该时钟应用于 DoubleAnimation 的 TargetName 和 TargetProperty 所指定的对象和属性。 在本例中,计时系统将时钟应用于名为“MyRectangle”的对象的 Opacity 属性。
虽然也会为 Storyboard 创建一个时钟,但未对任何属性应用该时钟。 该时钟的用途是控制其子时钟(为 DoubleAnimation 创建的时钟)。
若要使动画反映数据绑定或动画更改,必须重新生成其时钟。 系统不会为您自动生成时钟。 若要使动画反映更改,请使用 BeginStoryboard 或 Begin 方法重新应用其演示图板。 当使用其中的任何一种方法时,动画将重新启动。 在代码中,可以使用 Seek 方法将演示图板移回到其从前的位置。
有关绑定有数据的动画的示例,请参见 Key Spline Animation Sample(关键样条动画示例)。 有关动画和计时系统的工作原理的更多信息,请参见动画和计时系统概述。
其他动画处理方式
此概述中的示例演示如何使用演示图板进行动画处理。 如果使用代码,则可以采用一些其他方法进行动画处理。 有关更多信息,请参见 属性动画技术概述。
动画示例
以下示例可以帮助您开始向应用程序添加动画。
From, To, and By Animation Target Values Sample(From、To 和 By 动画目标值示例)
演示不同的 From/To/By 设置。
Animation Timing Behavior Sample(动画计时行为示例)
演示可控制动画计时行为的不同方法。 此示例还演示如何绑定动画目标值数据。
相关主题
标题 |
说明 |
---|---|
列出用于解决与动画有关的问题(如性能)的有用提示。 |
|
描述如何使用关键帧、动画类或逐帧回调来扩展动画系统。 |
|
描述如何创建在两个值之间转换的动画。 |
|
描述如何使用多个目标值创建动画(包括控制内插方法的功能)。 |
|
说明如何将数学公式应用于动画以获得真实行为(如反弹)。 |
|
描述如何沿复杂路径移动或旋转对象。 |
|
描述使用演示图板、本地动画、时钟以及逐帧动画的属性动画。 |
|
描述如何将演示图板与多个时间线一起使用,以创建复杂动画。 |
|
描述动画中使用的 Timeline 类型和属性。 |
|
描述 Timeline 和 Clock 对象上可用于在时间线中的各点上执行代码的事件(如开始、暂停、继续、跳过或停止)。 |
|
包含演示在应用程序中使用动画和时间线的代码示例。 |
|
包含演示在应用程序中使用 Clock 对象的代码示例。 |
|
包含演示在应用程序中使用关键帧动画的代码示例。 |
|
包含演示在应用程序中使用路径动画的代码示例。 |
参考
修订记录
日期 |
修订记录 |
原因 |
---|---|---|
2010 年 10 月 |
添加了缺少的 Visual Basic 代码段。 |
客户反馈 |