zoukankan      html  css  js  c++  java
  • WPF中的动画——(六)演示图板

    前面所介绍的都是单一的动画,它只能修改单一属性。有的时候,我们需要将一组动画一起进行,对于一个按钮,我们可能有如下需求:

    • 选择该按钮时,该按钮增大并更改颜色。
    • 单击该按钮时,该按钮缩小并恢复其原始大小。
    • 该按钮变成禁用时,缩小且不透明度缩减到 50%。

    每个操作都同时对应进行着两个动画,此时用我们就需要用到TimelineGroup了,前文介绍TimeLine的时候已经介绍过它了,它可以将多个TimeLine封装成一个统一调度。但TimeLine是一个抽象基类,我们通常使用的是它的子类演示图板(Storyboard)。

    演示图板(Storyboard) 是一种为其所包含的时间线提供目标信息的容器时间线。 演示图板可以包含任意类型的 Timeline,包括其他容器时间线和动画。

        var widthAnimation = new DoubleAnimation() { To = 250, FillBehavior = FillBehavior.Stop };
        var opacityAnimation = new DoubleAnimation() { From = 1, To = 0, FillBehavior = FillBehavior.Stop };

        var storyBoard = new Storyboard() { Duration = TimeSpan.FromSeconds(2) };
        storyBoard.Children.Add(widthAnimation);
        storyBoard.Children.Add(opacityAnimation);

        Storyboard.SetTargetProperty(widthAnimation, new PropertyPath("Width"));
        Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath("Opacity"));

        storyBoard.Begin(button);

    这个例子简单的演示了如何使用StoryBoard,由于Storyboard经常使用与XAML,这里也介绍一下XAML中的写法:

        <Storyboard x:Key="storyBoard">
            <DoubleAnimation Storyboard.TargetProperty="Width" To="250" FillBehavior="Stop"/>
            <DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" FillBehavior="Stop"/>
        </Storyboard>

    使用方式如下:

        var storyBoard = this.FindResource("storyBoard") as Storyboard;
        storyBoard.Begin(button);

    比直接用代码编写更加简单。

     

    两个附加属性:

    Storyboard.TargetProperty:

    由于StoryBoard对应着多个属性的变化,因此不能用UIElement.BeginAnimation的方式执行,而采用Storyboard.TargetProperty附加属性来写入。

    Storyboard.TargetName:

    Storyboard也可以通知控制多个对象,此时的对象就不能直接在Storyboard.Begin函数中执行,而是通过Storyboard.TargetProperty附加属性写入。

        <Storyboard x:Key="storyBoard">
            <DoubleAnimation
    Storyboard.TargetName="button" Storyboard.TargetProperty="Width" To="250" FillBehavior="Stop"/>
            <DoubleAnimation
    Storyboard.TargetName="button" Storyboard.TargetProperty="Opacity" From="1" To="0" FillBehavior="Stop"/>
        </Storyboard>

    这种方式下,执行storyboard的时候也不用在传入对象了

        var storyBoard = this.FindResource("storyBoard") as Storyboard;
        storyBoard.
    Begin();

     

    控制Storyboard

    前面已经介绍过,Storyboard 像Clock方法一样,直接封装了Begin、 Seek、 Stop、 Pause、ResumeRemove等几个函数,在代码中可以直接使用。另外,在XAML中,Storyboard是可以直接在触发器中(EventTriggerDataTriggerTrigger)使用的,如下就是一个简单的例子:

        <Window.Resources>
            <Storyboard x:Key="storyBoard">
                <DoubleAnimation Storyboard.TargetName="button" Storyboard.TargetProperty="Width" To="250" FillBehavior="Stop"/>
                <DoubleAnimation Storyboard.TargetName="button" Storyboard.TargetProperty="Opacity" From="1" To="0" FillBehavior="Stop"/>
            </Storyboard>
        </Window.Resources>
        <Window.Triggers>
            <EventTrigger RoutedEvent="Loaded" >
                <
    BeginStoryboard Storyboard="{StaticResource storyBoard}" />
            </EventTrigger>
        </Window.Triggers>

    可以看到,这儿用到了一个系统提供的名为BeginStoryboard的TriggerAction,同样也提供了SeekStoryboard、 StopStoryboard、 PauseStoryboard、ResumeStoryboard、RemoveStoryboard等几个TriggerAction。一个稍微复杂点的例子如下:

        <Window.Resources>
            <Storyboard x:Key="storyBoard">
                <DoubleAnimation Storyboard.TargetName="button" Storyboard.TargetProperty="Width" To="250" FillBehavior="Stop"/>
                <DoubleAnimation Storyboard.TargetName="button" Storyboard.TargetProperty="Opacity" From="1" To="0" FillBehavior="Stop"/>
            </Storyboard>
        </Window.Resources>
        <Window.Triggers>
            <EventTrigger RoutedEvent="MouseEnter" >
                <BeginStoryboard Name="storyBegin" Storyboard="{StaticResource storyBoard}" />
            </EventTrigger>
            <EventTrigger RoutedEvent="MouseLeave" >
                <RemoveStoryboard BeginStoryboardName="storyBegin" />
            </EventTrigger>
        </Window.Triggers>

    另外,微软提供的Interaction也能在XAML中执行Storyboard的控制:

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseEnter">
                <ei:ControlStoryboardAction Storyboard="{StaticResource storyBoard}" ControlStoryboardOption="Play" />
            </i:EventTrigger>
            <i:EventTrigger EventName="MouseLeave">
                <ei:ControlStoryboardAction Storyboard="{StaticResource storyBoard}" ControlStoryboardOption="Stop" />
            </i:EventTrigger>
        </i:Interaction.Triggers>

    由于微软的Interaction扩展在MVVM模式下非常有用,扩展性也非常好,这种方式很多时候更方便。关于Interaction的使用方式,请参看园子里的这篇文章:Interaction triggers in WPF

     

    参考资料:

    演示图板概述

     

  • 相关阅读:
    ural(Timus) 1019 Line Painting
    ACMICPC Live Archive 2031 Dance Dance Revolution
    poj 3321 Apple Tree
    其他OJ 树型DP 选课
    poj 3548 Restoring the digits
    ACMICPC Live Archive 3031 Cable TV Network
    递归循环获取指定节点下面的所有子节点
    手动触发asp.net页面验证控件事件
    子级Repeater获取父级Repeater绑定项的值
    没有列名的数据绑定
  • 原文地址:https://www.cnblogs.com/TianFang/p/4083690.html
Copyright © 2011-2022 走看看