版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons)
场景(Storyboard),它还有个名字叫故事版,就是增强的时间线,先是把一组独立的动画组织在一个Storyboard元素中,安排好他们的协作关系,然后指定哪个动画由哪个UI元素,哪个属性负责完成(关键帧动画是串行执行的一组动画,场景则是并行执行的一组动画),而且具有控制动画播放的能力—暂停、停止以及播放位置。Storyboard类提供的最基本功能是,能够使用TargetProperty和TargetName属性指向某个特定属性和特定元素(TargetProperty属性和TargetName属性都是附加属性)
XAML代码:
<Grid Margin="6">
<!--页面布局-->
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="80"/>
</Grid.ColumnDefinitions>
<!--(红)-->
<Border BorderBrush="Gray" BorderThickness="1" Grid.Row="0">
<Ellipse x:Name="ballR" Height="36" Width="36" Fill="Red" HorizontalAlignment="Left">
<Ellipse.RenderTransform>
<TranslateTransform x:Name="ttR"/>
</Ellipse.RenderTransform>
</Ellipse>
</Border>
<!--(绿)-->
<Border BorderBrush="Gray" BorderThickness="1" Grid.Row="1">
<Ellipse x:Name="ballG" Height="36" Width="36" Fill="Green" HorizontalAlignment="Left">
<Ellipse.RenderTransform>
<TranslateTransform x:Name="ttG"/>
</Ellipse.RenderTransform>
</Ellipse>
</Border>
<!--(蓝)-->
<Border BorderBrush="Gray" BorderThickness="1" Grid.Row="2">
<Ellipse x:Name="ballB" Height="36" Width="36" Fill="Blue" HorizontalAlignment="Left">
<Ellipse.RenderTransform>
<TranslateTransform x:Name="ttB"/>
</Ellipse.RenderTransform>
</Ellipse>
</Border>
<Button Content="点击" Grid.Column="1" Grid.RowSpan="3" Height="153" VerticalAlignment="Top" Click="Button_Click"/>
</Grid>
C#后台代码:
private void Button_Click(object sender, RoutedEventArgs e)
{
Duration duration = new Duration(TimeSpan.FromMilliseconds(600));
//红色小球匀速移动
DoubleAnimation daRx = new DoubleAnimation();
daRx.Duration = duration;
daRx.To = 400;
//绿色小球变速运动
DoubleAnimationUsingKeyFrames dakGx = new DoubleAnimationUsingKeyFrames();
dakGx.Duration = duration;
SplineDoubleKeyFrame keyFrameG = new SplineDoubleKeyFrame(400, KeyTime.FromPercent(1.0));
keyFrameG.KeySpline = new KeySpline(1, 0, 0, 1);
dakGx.KeyFrames.Add(keyFrameG);
//蓝色小球变速运动
DoubleAnimationUsingKeyFrames dakBx = new DoubleAnimationUsingKeyFrames();
dakBx.Duration = duration;
SplineDoubleKeyFrame kfB = new SplineDoubleKeyFrame(400, KeyTime.FromPercent(1.0));
kfB.KeySpline = new KeySpline(0, 1, 1, 0);
dakBx.KeyFrames.Add(kfB);
//创建场景
Storyboard storyboard = new Storyboard();
Storyboard.SetTargetName(daRx, "ttR");
Storyboard.SetTargetProperty(daRx, new PropertyPath(TranslateTransform.XProperty));
Storyboard.SetTargetName(dakGx, "ttG");
Storyboard.SetTargetProperty(dakGx, new PropertyPath(TranslateTransform.XProperty));
Storyboard.SetTargetName(dakBx, "ttB");
Storyboard.SetTargetProperty(dakBx, new PropertyPath(TranslateTransform.XProperty));
storyboard.Duration = duration;
storyboard.Children.Add(daRx);
storyboard.Children.Add(dakGx);
storyboard.Children.Add(dakBx);
storyboard.Begin(this);
storyboard.Completed += (a, b) => { MessageBox.Show(ttR.X.ToString()); };
}
事件触发器:可以在以下几个位置定义事件触发器。
- 在样式中(Style.Triggers集合)。
- 在数据模板中(DataTemplate.Triggers集合)。
- 在控件模板中(ControlTemplate. Triggers集合)。
- 直接在元素中定义事件触发器(FrameworkElement.Triggers集合)。
有三种基本类型的WPF触发器:属性触发器、数据触发器以及事件触发器。使用触发器是关联动画最常见的方式
XAML代码:
<Button Width="200" Height="80" Content="事件触发器" FontSize="20">
<!--元素触发器-->
<Button.Triggers>
<!--定义事件触发器-->
<EventTrigger RoutedEvent="Button.Click">
<!--执行一个动作-->
<EventTrigger.Actions>
<!--开始故事版-->
<BeginStoryboard>
<!--创建一个故事版-->
<Storyboard>
<!--创建一个-->
<DoubleAnimation Storyboard.TargetProperty="Width" To="350" RepeatBehavior="Forever" Duration="0:0:3"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Button.Triggers>
</Button>
<!--点击按钮“事件触发器”的时候便开始动画,宽度变成350,然后一直循环动画-->
控制场景的类:
-
- PauseStoryboard:停止播放动画并且保持当前位置
- ResumeStoryboard:恢复播放暂停的动画
- StopStoryboard:停止播放动画,并将动画时钟重新设置到开始位置
- SeekStoryboard:跳到动画时间线中的特定位置,如果当前动画正在播放,就继续从新位置播放,如果当前动画是暂停的,就继续保持暂停。
- SetStoryboardSpeedRatio:改变整个场景的SpeedRatio属性值。
- SkipStoryboardToFill:将场景移动到时间线的终点。FillBehavior属性设置为HoldEnd,动画继续保持最后的值。
- RemoveStoryboard:移除场景,停止所有正在运行的动画,并将属性返回为原来的、最后一次设置的数值。
为成功的执行这些动作,必须在同一个Triggers集合中定义所有的触发器,如果将BeginStoryboard动作的触发器和PauseStoryboard动作的触发器放置到不同的集合中,PauseStoryboard动作就无法工作。
场景事件:
- Completed:动画已经到达终点
- CurrentGlobalSpeedInvalidated:速度发生了变化,或者动画被暂停、重新开始、停止或移到某个新的位置。
- CurrentStateInvalidated:动画已经开始或结束。
- CurrentTimeInvalidated:动画时钟已经向前移动了一个步长,正在更改动画。当动画开始、停止或结束时也会引发该事件。
- RemoveRequested:动画正在被移除。