在 XAML 中实现和包含动画的基本 WPF 方法





5.00/5 (6投票s)
本文将尝试描述在 WPF 中实现动画的基础方法。
引言
本文将尝试描述在 WPF 中实现动画的基础方法。
背景
学习如何实现动画并非成为 C# WPF 开发人员的必备技能。然而,对于图形密集型应用而言,动画非常宝贵。另一方面,即使对于数据密集型的 UI 应用程序,虽然可能没有太多动画,但在某些地方加入动画可以突出关键点,并直接聚焦于部分用户功能。在 UI 中无视可用性地放置动画是毫无意义的,但恰当地使用并增加特定价值可以增强用户界面的可用性。
在 WPF 应用程序的 XAML 中实现动画既简单又直接。对于初学者来说,它可能看起来很复杂,好像是一项艰巨的任务。但实际上,它一点也不复杂。在下面的文章中,我将尝试通过几个简单的步骤来介绍如何使用 XAML 放置简单的动画。一旦我们知道了如何在 XAML 代码中放置动画,就没有多少其他需要了解的了。之后,更炫酷和复杂的动画将完全包含在动画代码(其 Storyboard
)本身中,而插入这段动画与插入简单的动画到 XAML 代码中的方式相同,都很简单。
“BeginStorybaord
” 是在 WPF 中实现动画的 XAML 标签。如果我们记住这一点,我们就能愉快地进行 XAML 动画编程!!
Using the Code
练习 1
- 让我们从一个简单的
TextBlock
开始,我们将在这里显示一行错误消息,文本为红色。(正如你所料,还没有动画) - 然后,我们将在
BeginStoryboard
中实现一个“Storyboard
”来使文本闪烁。(使用简单动画实现。)
练习 2
- 创建一个简单的
Button
,文本为“Submit”(无动画)。 - 鼠标悬停时切换背景(通过动画实现)。
- 再次,增强此按钮,使其呈椭圆形,并带有几个不同颜色的内圆。(还没有动画)
- 进一步增强,插入一个“storyboard”来改变此按钮的内圆/椭圆颜色,在鼠标悬停时切换颜色。(通过动画实现。)
练习 3
- 将我们在练习 1 和练习 2 中与控件(
TextBlock
和Button
)一起创建的这些 storyboards 放置在Windows.Resources
部分。 - 使用这些 storyboards 替换你在练习 1 和 2 中创建的内联 storyboards。
练习 4(可选,用于学习如何在 XAML 中插入动画)
- 此外,我们现在可以将 storyboards 放在一个 resource.xaml 文件中,并将其加载为
resource dictionary
(这一步是基础 XAML,与动画无关) - 使用 Blend、Photoshop、Illustrator 或任何其他图形工具创建更复杂的动画。(我将把这个留给您使用一些图形工具来创建更复杂的 storyboards)
- 将这个复杂的动画、第三方动画或由某图形设计师团队创建并移交的动画包含在
resources file
中,并将其加载到 WPF 项目中,作为 resource dictionary 加载。 - 使用“
key
”指向此 storyboard,就像您在BeginStoryboard
标签中插入简单动画一样。
练习 1
首先,让我们创建一个简单的 TextBlock
。
<TextBlock Foreground="Red" Text="Severe error, connection failed,
please check log for more details"></TextBlock>
现在,让我们添加动画,以便该 TextBlock
中的文本在加载时“闪烁”,方法是添加一个事件触发器。我们将在 Loaded
EventTrigger
的 Storyboard
中添加 DoubleAnimation
。
<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>
练习 2
让我们创建一个简单的按钮。
<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
使其看起来“圆润”,并带有几个内环(圆圈/椭圆),具有各种不同的背景颜色。我们将使用多个椭圆堆叠在一起,然后在鼠标悬停在按钮上时,通过为 ColorAnimation
实现 MouseEnter
事件触发器来为最内层的椭圆设置动画,改变其颜色。
<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>
在上面的示例中,我们为事件触发器创建了动画。然而,我们可以用同样的方式为任何类型的触发器使用动画。
练习 3
一旦我们创建了 Storyboard
并将其内联到 trigger
中,我们就可以将 Storyboard 代码移动到 resource section
,以便在适用时为多个控件重用。例如
<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}"/>
练习 4
现在,我们可以将 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>
这样做的好处是,我们可以包含任意数量的资源字典文件。我们可以将第三方创建的、由各种图形工具创建的或由其他团队创建的更复杂的 storyboards 放入多个 resource dictionary files
。然后将它们作为 Window.Resources
包含,并通过“Key
”引用它们,正如上面“练习 3”所示。
参考资料
更多阅读材料如下
- http://msdn.microsoft.com/en-us/library/windows/apps/xaml/jj819807.aspx
- http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh452703.aspx
- http://msdn.microsoft.com/en-us/library/System.Windows.Media.Animation.Storyboard(v=vs.110).aspx
- http://msdn.microsoft.com/en-us/library/System.Windows.Media.Animation(v=vs.110).aspx
历史
- 2014 年 5 月 5 日:初始版本