既然动画类是由一组有用的属性组成,那么,我们就会很容易想到,可以在XAML中定义一个动画。
比如说:
<DoubleAnimation From="20" To="60" Duration="0:0:5" AutoReverse="True" FillBehavior="Stop"/>
这就是一个Double类型的动画。
定义的动画放在哪里呢?一种选择是将它定义为资源,可以在后台代码中通过Resources或FindResource()得到,甚至可以在用之前再调整动画的属性,来得到不同的效果。动画放置在资源中,例如:
<Window.Resources>
<Storyboard x:Key="sb">
<DoubleAnimation From="20" To="60" Duration="0:0:5" AutoReverse="True" FillBehavior="Stop"/>
</Storyboard>
</Window.Resources>
另外一个放置动画的地方就是Triggers的Action中。在EventTrigger中包含Storyboard,是最典型的用法。例如:
<Button Content="xirihanlin">
<Button.Background>
<LinearGradientBrush>
<GradientStop Color="Orange" Offset="0"/>
<GradientStop Color="GreenYellow" Offset="0.5"/>
<GradientStop Color="Orange" Offset="1"/>
</LinearGradientBrush>
</Button.Background>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Loaded">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[1].Color"
From="GreenYellow" To="White" Duration="0:0:2"
AutoReverse="True" RepeatBehavior="Forever"/>
<DoubleAnimation Storyboard.TargetProperty="Background.GradientStops[1].Offset"
From="0" To="1" Duration="0:0:2"
AutoReverse="True" RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
DoubleAnimation和ColorAnimation被放置在Storyboard中,而Storyboard被包裹在一个BeginStoryboard的动作里。当EventTrigger中的定义的事件(Button.Loaded)被激活时,就会执行BeginStoryboard这个动作(即播放动画)。
到这里,我们需要注意几件事情:
1)Storyboard可以作为一个容器,容纳一个或多个动画,因为它的Content属性是Children,是Timeline对象的集合(所有动画类的基类);
2)在XAML中,除非ColorAnimation等动画放置在Storyboard中,否则它们不能被初始化;
3)动画的播放需要指定两个重要的属性:TargetName和TargetProperty。TargetProperty在上面已经看到,TargerName被隐式指定,那就是Trigger的对象,在这里就是我们的Button;
4)Storyboard继承自Timeline,也能指定Duration、BeginTime等属性,因此,Storyboard上的属性设定与单独在每个子动画上做的设定效果可能会不同;
5)BeginStoryboard继承自TriggerAction,与它一起的还有其他好几个动作;
接下来重点看看TargetName和TargetProperty。
TargetProperty:它的类型是PropertyPath,它支持复杂的设置(如一个带许多子属性的属性),如在上述代码中的“Background.GradientStops[1].Color”。TargetProperty的语法是模仿C#访问属性时的键入,但不需要类型转换。执行时,Storyboard会假设Button的Backgound被设置成GradientStops属性中的某个对象,甚至假设该属性至少有两项,并且第二项有一个类型为Color的Color属性。如果这些假设中的任意一个不符合要求,那么动画就会失败。
当然,上面的代码是正确的,所以动画就能正常播放,效果如下图所示:
很漂亮的说~~~~
TargetName:在默认情况下,TargetName隐式指定为触发器(Trigger)的对象;如果在Style中使用动画,TargetName隐式指定为模板化的父对象。当然,你也可以设定为其他目标对象,但是,目标对象必须拥有TargetProperty所设定的属性。关于在Style中添加EventTrigger和Storyboard,有一个Demo,当鼠标在图片上时,图片放缩2倍,离开时,图片恢复到原来大小。执行的效果如下图所示:
代码见Demo。