在WPF应用程序开发中,虽然不一定要掌握动画的实现方法,但对于那些图形密集型的应用来说,动画是非常有价值的。即使对于那些数据密集型的UI应用程序,虽然可能不需要太多动画,但在某些地方适当地添加动画可以突出重点,直接聚焦于用户界面的特定功能。然而,如果没有考虑到可用性,盲目地在UI中添加动画是没有价值的。相反,如果能够恰当地使用动画,可以增强用户界面的可用性。
在WPF应用程序中,使用XAML实现动画是简单直接的。对于初学者来说,可能会觉得复杂,像是一个大工程。但实际上,它并不复杂。在下面的文章中,将尝试通过几个简单的步骤来介绍如何在XAML中放置简单的动画。一旦知道如何在XAML代码中放置动画,就没有更多的困难了。之后,更复杂和高级的动画完全包含在动画代码(它的Storyboard)本身中,插入这段动画的方式仍然像插入简单动画一样简单。
在XAML中实现WPF动画的标签是"BeginStoryboard"。如果记住这一点,将拥有一个愉快的动画XAML生活!
让从一个简单的TextBlock开始,将显示一条错误消息作为简单的红色文本。(如所猜,还没有动画)
然后将实现一个“Storyboard”,在BeginStoryboard内使文本闪烁。(使用简单的动画实现)
<TextBlock Foreground="Red" Text="严重错误,连接失败,请检查日志以获取更多详细信息">
</TextBlock>
现在让添加动画,使得这个TextBlock的文本在加载时“闪烁”,通过添加一个事件触发器。将在它的Storyboard中添加DoubleAnimation以实现Loaded事件触发器。
<TextBlock.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(TextBlock.Opacity)" From="1" To="0" AutoReverse="True" BeginTime="0:0:0" Duration="0:0:.125" RepeatBehavior="6x">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBlock.Triggers>
让创建一个简单的按钮,文本为“提交”(没有动画)。
<Button Width="100" Height="30" Content="Submit">
</Button>
让添加一个EventTrigger,在MouseEnter事件期间执行动画。让添加BeginStoryboard以及其中的Storyboard来在鼠标悬停在按钮上时动画按钮背景。然后,当运行这个并悬停在按钮上时,将看到按钮背景颜色从灰色切换到深绿色两次。
<Button Width="100" Height="30" Content="Submit">
<Button.Background>
<SolidColorBrush x:Name="innerCircleBrush" Color="Gray">
</SolidColorBrush>
</Button.Background>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="innerCircleBrush" Storyboard.TargetProperty="Color" From="Gray" To="DarkGreen" AutoReverse="True" BeginTime="0:0:0" Duration="0:0:.25" RepeatBehavior="2x">
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
(可选)现在,让变得有点花哨,创建一个按钮,并通过改变这个按钮控件的Template使其看起来“圆形”,有几个内部圆环(圆/椭圆)的不同颜色背景。将使用多个叠加的椭圆,然后将在鼠标悬停在按钮上时通过实现Storyboard的ColorAnimation来动画化最内部椭圆的颜色。
<Button Content="Submit">
<Button.Template>
<ControlTemplate>
<Grid>
<Ellipse Width="60" Height="60" Fill="SlateGray" VerticalAlignment="Center" HorizontalAlignment="Center">
</Ellipse>
<Ellipse Width="55" Height="55" Fill="LightGray" VerticalAlignment="Center" HorizontalAlignment="Center">
</Ellipse>
<Ellipse Width="45" Height="45" VerticalAlignment="Center" HorizontalAlignment="Center">
<Ellipse.Fill>
<SolidColorBrush x:Name="innerCircleBrush" Color="Gray">
</SolidColorBrush>
</Ellipse.Fill>
<Ellipse.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="innerCircleBrush" Storyboard.TargetProperty="Color" From="Gray" To="DarkGreen" AutoReverse="True" BeginTime="0:0:0" Duration="0:0:.25" RepeatBehavior="2x">
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Ellipse.Triggers>
</Ellipse>
<TextBlock Margin="2,0,0,2" Text="Submit" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center">
</TextBlock>
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
一旦创建了Storyboard并将其内联插入到触发器中,可以将Storyboard代码移动到资源部分,以便可以在多个控件中重用。例如:
<Window.Resources>
<Storyboard x:Key="toggleColorStoryboard">
<ColorAnimation Storyboard.TargetName="innerCircleBrush" Storyboard.TargetProperty="Color" From="Gray" To="DarkGreen" AutoReverse="True" BeginTime="0:0:0" Duration="0:0:.25" RepeatBehavior="2x">
</ColorAnimation>
</Storyboard>
</Window.Resources>
然后,可以像下面这样重用这个Storyboard,无论是对于创建的第一个基本按钮还是创建的花哨的圆形按钮。
<BeginStoryboard Storyboard="{StaticResource toggleColorStoryboard}" />
现在可以将Storyboard移动到项目中的一个单独文件中,称之为Dictionary1.xaml。这个资源字典文件的内容在将Storyboard代码移入其中后将如下所示。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Storyboard x:Key="toggleColorStoryboard">
<ColorAnimation Storyboard.TargetName="innerCircleBrush" Storyboard.TargetProperty="Color" From="Gray" To="DarkGreen" AutoReverse="True" BeginTime="0:0:0" Duration="0:0:.25" RepeatBehavior="2x">
</ColorAnimation>
</Storyboard>
</ResourceDictionary>
一旦这样做,让现在将这个资源字典包含到主要窗口xaml文件中,如下所示:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
这样做的好处是可以包含任意数量的资源字典文件。可以将第三方创建的更复杂的Storyboard或由各种图形工具或由其他团队创建的Storyboard放入多个资源字典文件中。然后作为Window.Resources包含它们,并像在上面的“练习3”中所示,通过“Key”引用它们。