65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (6投票s)

2014年5月6日

CPOL

5分钟阅读

viewsIcon

30726

本文将尝试描述在 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 EventTriggerStoryboard 中添加 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”所示。

参考资料

更多阅读材料如下

历史

  • 2014 年 5 月 5 日:初始版本
© . All rights reserved.