WPF中的动画——(六)演示图板

前面所介绍的都是单一的动画,它只能修改单一属性。有的时候,我们需要将一组动画一起进行,对于一个按钮,我们可能有如下需求:

  • 选择该按钮时,该按钮增大并更改颜色。
  • 单击该按钮时,该按钮缩小并恢复其原始大小。
  • 该按钮变成禁用时,缩小且不透明度缩减到 50%。

每个操作都同时对应进行着两个动画,此时用我们就需要用到TimelineGroup了,前文介绍TimeLine的时候已经介绍过它了,它可以将多个TimeLine封装成一个统一调度。但TimeLine是一个抽象基类,我们通常使用的是它的子类演示图板(Storyboard)。

演示图板(Storyboard) 是一种为其所包含的时间线提供目标信息的容器时间线。 演示图板可以包含任意类型的 Timeline,包括其他容器时间线和动画。

????var widthAnimation = new
DoubleAnimation() { To = 250, FillBehavior = FillBehavior.Stop };
????var opacityAnimation = new
DoubleAnimation() { From = 1, To = 0, FillBehavior = FillBehavior.Stop };

????var storyBoard = new
Storyboard() { Duration = TimeSpan.FromSeconds(2) };
????storyBoard.Children.Add(widthAnimation);
????storyBoard.Children.Add(opacityAnimation);

????Storyboard.SetTargetProperty(widthAnimation, new
PropertyPath("Width"));
????Storyboard.SetTargetProperty(opacityAnimation, new
PropertyPath("Opacity"));

????storyBoard.Begin(button);

这个例子简单的演示了如何使用StoryBoard,由于Storyboard经常使用与XAML,这里也介绍一下XAML中的写法:

????<Storyboard x:Key="storyBoard">
????????<DoubleAnimation Storyboard.TargetProperty="Width" To="250" FillBehavior="Stop"/>
????????<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" FillBehavior="Stop"/>
????</Storyboard>

使用方式如下:

????var storyBoard = this.FindResource("storyBoard") as
Storyboard;
????storyBoard.Begin(button);

比直接用代码编写更加简单。

?

两个附加属性:

Storyboard.TargetProperty:

由于StoryBoard对应着多个属性的变化,因此不能用UIElement.BeginAnimation的方式执行,而采用Storyboard.TargetProperty附加属性来写入。

Storyboard.TargetName:

Storyboard也可以通知控制多个对象,此时的对象就不能直接在Storyboard.Begin函数中执行,而是通过Storyboard.TargetProperty附加属性写入。

????<Storyboard x:Key="storyBoard">
????????<DoubleAnimation
Storyboard.TargetName="button" Storyboard.TargetProperty="Width" To="250" FillBehavior="Stop"/>
????????<DoubleAnimation
Storyboard.TargetName="button" Storyboard.TargetProperty="Opacity" From="1" To="0" FillBehavior="Stop"/>
????</Storyboard>

这种方式下,执行storyboard的时候也不用在传入对象了

????var storyBoard = this.FindResource("storyBoard") as
Storyboard;
????storyBoard.Begin();

?

控制Storyboard

前面已经介绍过,Storyboard 像Clock方法一样,直接封装了Begin、 Seek、 Stop、 Pause、Resume、Remove等几个函数,在代码中可以直接使用。另外,在XAML中,Storyboard是可以直接在触发器中(EventTriggerDataTriggerTrigger)使用的,如下就是一个简单的例子:

????<Window.Resources>
????????<Storyboard x:Key="storyBoard">
????????????<DoubleAnimation Storyboard.TargetName="button" Storyboard.TargetProperty="Width" To="250" FillBehavior="Stop"/>
????????????<DoubleAnimation Storyboard.TargetName="button" Storyboard.TargetProperty="Opacity" From="1" To="0" FillBehavior="Stop"/>
????????</Storyboard>
????</Window.Resources>
????<Window.Triggers>
????????<EventTrigger RoutedEvent="Loaded" >
????????????<BeginStoryboard Storyboard="{StaticResource storyBoard}" />
????????</EventTrigger>
????</Window.Triggers>

可以看到,这儿用到了一个系统提供的名为BeginStoryboard的TriggerAction,同样也提供了SeekStoryboard、 StopStoryboard、 PauseStoryboard、ResumeStoryboard、RemoveStoryboard等几个TriggerAction。一个稍微复杂点的例子如下:

????<Window.Resources>
????????<Storyboard x:Key="storyBoard">
????????????<DoubleAnimation Storyboard.TargetName="button" Storyboard.TargetProperty="Width" To="250" FillBehavior="Stop"/>
????????????<DoubleAnimation Storyboard.TargetName="button" Storyboard.TargetProperty="Opacity" From="1" To="0" FillBehavior="Stop"/>
????????</Storyboard>
????</Window.Resources>
????<Window.Triggers>
????????<EventTrigger RoutedEvent="MouseEnter" >
????????????<BeginStoryboard Name="storyBegin" Storyboard="{StaticResource storyBoard}" />
????????</EventTrigger>
????????<EventTrigger RoutedEvent="MouseLeave" >
????????????<RemoveStoryboard
BeginStoryboardName="storyBegin" />
????????</EventTrigger>
????</Window.Triggers>

另外,微软提供的Interaction也能在XAML中执行Storyboard的控制:

????<i:Interaction.Triggers>
????????<i:EventTrigger EventName="MouseEnter">
????????????<ei:ControlStoryboardAction Storyboard="{StaticResource storyBoard}" ControlStoryboardOption="Play" />
????????</i:EventTrigger>
????????<i:EventTrigger EventName="MouseLeave">
????????????<ei:ControlStoryboardAction Storyboard="{StaticResource storyBoard}" ControlStoryboardOption="Stop" />
????????</i:EventTrigger>
????</i:Interaction.Triggers>

由于微软的Interaction扩展在MVVM模式下非常有用,扩展性也非常好,这种方式很多时候更方便。关于Interaction的使用方式,请参看园子里的这篇文章:Interaction triggers in WPF

?

参考资料:

演示图板概述

?

时间: 2024-11-05 19:54:01

WPF中的动画——(六)演示图板的相关文章

WPF中的动画——(五)路径动画

原文:WPF中的动画--(五)路径动画 路径动画是一种专门用于将对象按照指定的Path移动的动画,虽然我们也可以通过控制动画的旋转和偏移实现对象的移动,但路径动画更专业,它的实现更加简洁明了. 路径动画中最常用的是MatrixAnimationUsingPath,它通常用于控制对象的MatrixTransform,一个简单的例子如下: 1 <Canvas > 2 <Canvas.Resources> 3 <PathGeometry x:Key="path"

WPF中的动画——(三)时间线(TimeLine)(转)

WPF中的动画——(三)时间线(TimeLine) 时间线(TimeLine)表示时间段. 它提供的属性可以让控制该时间段的长度.开始时间.重复次数.该时间段内时间进度的快慢等等.在WPF中内置了如下几种TimeLine: AnimationTimeline :前面已经介绍过,主要用于属性的过渡,这种是最常见的动画. MediaTimeline:用于控制媒体文件播放的时间线. ParallelTimeline:ParallelTimeline 是一种可对其他时间线进行分组的时间线,可用于实现较复

WPF中的动画——(四)缓动函数(转)

WPF中的动画——(四)缓动函数 缓动函数可以通过一系列公式模拟一些物理效果,如实地弹跳或其行为如同在弹簧上一样.它们一般应用在From/To/By动画上,可以使得其动画更加平滑. var widthAnimation = new DoubleAnimation()    {        From = 0,        To = 320,        Duration = TimeSpan.FromSeconds(1),        EasingFunction = new BackEa

WPF中的动画——(五)关键帧动画(转)

WPF中的动画——(五)关键帧动画 与 From/To/By 动画类似,关键帧动画以也可以以动画形式显示目标属性值. 和From/To/By 动画不同的是, From/To/By 动画只能控制在两个状态之间变化,而关键帧动画则可以在多个状态之间变化,例如,对于前面那个改变按钮宽度的例子,如果我们要实现如下效果: 在2秒时将宽度从 0变为350 在7秒时将宽度变为50 在9秒的时候将其宽度变为200 虽然我们可以用三个From/To/By 动画组合实现类似效果,但是这样一来麻烦,二来要感知动画完成

WPF中的动画——(二)From/To/By 动画(二)

WPF中的动画——(二)From/To/By 动画 我们所实现的的动画中,很大一部分是让一个属性在起始值和结束值之间变化,例如,我在前文中实现的改变宽度的动画: var widthAnimation = new DoubleAnimation()    {        From = 0,        To = 320,        Duration = TimeSpan.FromSeconds(2),        RepeatBehavior = RepeatBehavior.Forev

WPF中的动画——(一)基本概念

WPF的一个特点就是支持动画,我们可以非常容易的实现漂亮大方的界面.首先,我们来复习一下动画的基本概念.计算机中的动画一般是定格动画,也称之为逐帧动画,它通过每帧不同的图像连续播放,从而欺骗眼和脑产生动画效果.其原理在维基百科上有比较详尽的解释,这里就不多介绍了. 也就是说,我们要产生动画,只需要连续刷新界面即可.例如,我们要实现一个宽度变化的按钮的动画,可以用如下方式来实现: private void MainWindow_Loaded(object sender, RoutedEventAr

WPF中的动画——(五)关键帧动画

与 From/To/By 动画类似,关键帧动画以也可以以动画形式显示目标属性值. 和From/To/By 动画不同的是, From/To/By 动画只能控制在两个状态之间变化,而关键帧动画则可以在多个状态之间变化,例如,对于前面那个改变按钮宽度的例子,如果我们要实现如下效果: 在2秒时将宽度从 0变为350 在7秒时将宽度变为50 在9秒的时候将其宽度变为200 虽然我们可以用三个From/To/By 动画组合实现类似效果,但是这样一来麻烦,二来要感知动画完成事件,不方便在XAML中使用.此时我

WPF中的动画——(三)时间线(TimeLine)

时间线(TimeLine)表示时间段. 它提供的属性可以让控制该时间段的长度.开始时间.重复次数.该时间段内时间进度的快慢等等.在WPF中内置了如下几种TimeLine: AnimationTimeline?:前面已经介绍过,主要用于属性的过渡,这种是最常见的动画. MediaTimeline:用于控制媒体文件播放的时间线. ParallelTimeline:ParallelTimeline?是一种可对其他时间线进行分组的时间线,可用于实现较复杂的动画. Storyboard?:一种特殊的?Pa

WPF中的动画——(二)From/To/By 动画

我们所实现的的动画中,很大一部分是让一个属性在起始值和结束值之间变化,例如,我在前文中实现的改变宽度的动画: var widthAnimation = new DoubleAnimation()    {        From = 0,        To = 320,        Duration = TimeSpan.FromSeconds(2),        RepeatBehavior = RepeatBehavior.Forever,    }; button.BeginAnim