zoukankan      html  css  js  c++  java
  • WPF动画基础及实例

    1.介绍

    在之前做winform中, 也做过一些动画效果, 但是整个动画都需要我们自己去编写, 利用计时器或线程去直接操作UI元素的属性, 然而在WPF中, 则是通过一种全新的基于属性的动画系统, 改变了传统的开发模式。

    2.传统的方式

    (1).创建一个周期性触发的定时器(例如, 间隔50毫秒的刷新动作)

    (2).当每次出发计时器时, 关联的事件处理程序会执行一些与界面UI元素相关的细节。(例如,改变窗体的大小)

    (3).重新绘制整个界面元素。

    缺点:

    1.修改一个效果的时候,要比想象中复杂, 你要追加一个效果,必须编写所有的代码, 甚至变得更加复杂。

    2.动画的帧率固定, 然后渲染基于基础的GDI+绘图, 并不支持显卡级别的渲染模式。

    3.复杂的动画需要更复杂的代码实现, 不仅开发难, 维护更难。

    3.基于属性的WPF动画

    在WPF中, 动画使用了一个完全不同的模型。本质上, WPF动画只不过是在一段时间间隔内修改依赖性

    属性值的一种方式。

    优点:

    1.一套完整的动画封装, System.Windows.Media.Aniation 空间下已经提供了多数动画类。

    2.完成不同的特效, 只需要微调部分属性即可。

    3.支持硬件加速。

    4.基本动画

    正如上面所说, 每一个动画依赖于一个依赖项属性。原理则是通过修改其属性值到达效果。

    WPF所有的动画类中, 都继承于 Animatable , 该抽象类提供动画支持 , 具体看如下:

    微软官方文档连接

    类图如下所示:

    5.示例(一个基本的收缩动画)

    gif效果图, 演示可以两个动画, 一个在窗体加载时向上下张开, 一个关闭时上下向中间收缩动画。

     

    6.代码创建

    1.创建 Storyboard 对象, 用于装配子动画对象和属性信息。
    2.由于控制Margin, 用到的属于 Thickness 结构的数据类型, 所以需要创建 ThicknessAnimation 对象。
    3.设置 ThicknessAnimation 其子属性的参数: 动画时间、 初始值、结束值。
    4.绑定其元素对象GridMain
    5.绑定依赖属性 Margin
    6.添加到 Storyboard 容器中
    7.运行动画

                System.Windows.Media.Animation.Storyboard sb = new System.Windows.Media.Animation.Storyboard();
                System.Windows.Media.Animation.ThicknessAnimation dmargin = new System.Windows.Media.Animation.ThicknessAnimation();
                dmargin.Duration = new TimeSpan(0, 0, 0, 0, 300);
                dmargin.From = new Thickness(0, 300, 0, 300);
                dmargin.To = new Thickness(0, 0, 0, 0);
                System.Windows.Media.Animation.Storyboard.SetTarget(dmargin, GridMain);
                System.Windows.Media.Animation.Storyboard.SetTargetProperty(dmargin, new PropertyPath("Margin", new object[] { }));
                sb.Children.Add(dmargin);
                sb.Begin();

       注: GridMain实际为xmal中 Grid窗体的 Name="GridMain"

    ThicknessAnimation 属性介绍:

    .Duration

    Duration属性很简单, 它就是在动画开始时刻和结束时刻之间的时间间隔(时间间隔单位以毫秒、分钟、小时或者其他喜欢使用的任何单位)。Duration和TimeSpan非常类似, 并且Duration结构定义了一个隐式转换,能够根据需要将System.TimeSpan转为System.Windows.Duration。

    这正是为什么下面的代码完全可以和上面的一样使用:

      dmargin.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 300));

    .From

    From属性用于设置初始值, 例如上例中,Margin设置为上下边距为300.

    .To

    To属性用于设置动画结束的值。如上中, 结束动画完成, Grid的边距则为0.

    7.XAML创建动画

    1.相对于代码创建动画, Xaml方式创建动画要简单的多。添加 Storyboard键 , 然后添加 hicknessAnimation键和绑定参数

    <Storyboard x:Key="Loading">
                <ThicknessAnimation Duration="0:0:0.3" To="0" From="0,300,0,300" 
                                    Storyboard.TargetName="GridMain" Storyboard.TargetProperty="Margin" />
    </Storyboard>

    2.利用时间触发器, 关联启动事件, 进行动画的加载。

     <Window.Triggers>
            <EventTrigger  RoutedEvent="Loaded" >
                <BeginStoryboard Storyboard="{StaticResource Loading}"/>
            </EventTrigger>
     </Window.Triggers>

    剩余部分:

    关闭部分动画的收缩代码实现:

                System.Windows.Media.Animation.ThicknessAnimation dmargin = new System.Windows.Media.Animation.ThicknessAnimation();
                dmargin.Duration = new Duration(new TimeSpan(0, 0, 0, 0, 300));
                dmargin.From = GridMain.Margin;
                dmargin.To = new Thickness(0, 300, 0, 300);
                System.Windows.Media.Animation.Storyboard.SetTarget(dmargin, GridMain);
                System.Windows.Media.Animation.Storyboard.SetTargetProperty(dmargin, new PropertyPath("Margin", new object[] { }));
                sb.Children.Add(dmargin);

      前台XAML代码的实现方式,  关闭的事件中, 绑定的TextBlock.MouseLeftButtonDown 事件, 完整代码(包含上面部分):

    <Window.Resources>
            <Storyboard x:Key="Loading">
                <ThicknessAnimation Duration="0:0:0.3" To="0" From="0,300,0,300" 
                                    Storyboard.TargetName="GridMain" Storyboard.TargetProperty="Margin" />
            </Storyboard>
            
            <Storyboard x:Key="Closing">
                <ThicknessAnimation FillBehavior="Stop" Duration="0:0:0.6" To="0,300,0,300" From="0" Storyboard.TargetName="GridMain" 
                                    Storyboard.TargetProperty="Margin" Completed="Sb_Completed"/>
            </Storyboard>
        </Window.Resources>
        <Window.Triggers>
            <EventTrigger  RoutedEvent="Loaded" >
                <BeginStoryboard Storyboard="{StaticResource Loading}"/>
            </EventTrigger>
            <EventTrigger RoutedEvent="TextBlock.MouseLeftButtonDown">
                <BeginStoryboard Storyboard="{StaticResource Closing}"  />
            </EventTrigger>
     </Window.Triggers>
  • 相关阅读:
    主线程MainThread与渲染线程RenderThread
    杀死进程的几种方式
    Android App的设计架构:MVC,MVP,MVVM与架构经验谈
    动画完全解析(二):补间动画原理及自定义动画
    SublimeText教程
    JqGrid自定义的列
    js 除法 取整
    js日期字符串增加天数的函数
    Oracle中的rownum和rowid
    jQuery判断对象是否是函数
  • 原文地址:https://www.cnblogs.com/zh7791/p/9305005.html
Copyright © 2011-2022 走看看