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

     

    参考资料:

    演示图板概述

     

  • 相关阅读:
    HDU 5791 Two (DP)
    POJ 1088 滑雪 (DPor记忆化搜索)
    LightOJ 1011
    POJ 1787 Charlie's Change (多重背包 带结果组成)
    HDU 5550 Game Rooms (ccpc2015 K)(dp)
    HDU 5542 The Battle of Chibi (ccpc 南阳 C)(DP 树状数组 离散化)
    HDU 5543 Pick The Sticks (01背包)
    HDU 5546 Ancient Go (ccpc2015南阳G)
    NB-IoT的DRX、eDRX、PSM三个模式 (转载,描述的简单易懂)
    MQTT 嵌入式端通讯协议解析(转)
  • 原文地址:https://www.cnblogs.com/TianFang/p/4083690.html
Copyright © 2011-2022 走看看