WPF实现动画效果
作者:痕迹g 发布时间:2023-06-26 17:49:44
学习平台
微软开发者博客:
https://devblogs.microsoft.com/?WT.mc_id=DT-MVP-5003986
微软文档与学习:
https://docs.microsoft.com/zh-cn/?WT.mc_id=DT-MVP-5003986
微软开发者平台:
https://developer.microsoft.com/en-us/?WT.mc_id=DT-MVP-5003986
1.介绍
在之前做winform中, 也做过一些动画效果, 但是整个动画都需要我们自己去编写, 利用计时器或线程去直接操作UI元素的属性, 然而在WPF中, 则是通过一种全新的基于属性的动画系统, 改变了传统的开发模式。
2.传统的方式
(1).创建一个周期性触发的定时器(例如, 间隔50毫秒的刷新动作)
(2).当每次出发计时器时, 关联的事件处理程序会执行一些与界面UI元素相关的细节。(例如,改变窗体的大小)
(3).重新绘制整个界面元素。
缺点:
1.修改一个效果的时候,要比想象中复杂, 你要追加一个效果,必须编写所有的代码, 甚至变得更加复杂。
2.动画的帧率固定, 然后渲染基于基础的GDI+绘图, 并不支持显卡级别的渲染模式。
3.复杂的动画需要更复杂的代码实现, 不仅开发难, 维护更难。
3.基于属性的WPF动画
在WPF中, 动画使用了一个完全不同的模型。本质上, WPF动画只不过是在一段时间间隔内修改依赖性
属性值的一种方式。
优点:
1.一套完整的动画封装, System.Windows.Media.Animation空间下已经提供了多数动画类。
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键 , 然后添加 ThicknessAnimation键和绑定参数
<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>
来源:https://www.cnblogs.com/zh7791/p/9305005.html
猜你喜欢
- 1. 概述锁是Java并发编程中最重要的同步机制。锁除了让临界区互斥执行外,还可以让释放锁的线程获取同一个锁的线程发送消息。锁在实际使用时只
- 本篇博客我们继续的来聊SpringMVC的东西,下方我们将会聊到js、css这些静态文件的加载配置,以及服务器推送的两种实现方式。当然我们在
- 一、介绍knife4j增强版本的Swagger 前端UI,取名knife4j是希望她能像一把匕首一样小巧,轻量,并且功能强悍,更名也是希望把
- 介绍备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不破坏封装性的前提下,捕获并保存一个对象的内部状态,并在之后可
- 由于项目需要,需要用vs窗体程序实现播放视频的窗口的全屏和取消全屏。具体实现界面如图:这是初始状态,视频框的右上角就是控制全屏的按钮这是全屏
- 一、Shader基础知识1.1、什么是Shader在讲什么是Shader之前我们先看看下面两段代码 这两段代码实现的功能都是提取
- InputStreamReader 类1、概述转换流 java.io.InputStreamReader ,是Reader的子类,是从字节流
- 一、本地仓库初始化与远程仓库推送操作Idea 基本环境配置Github 配置Git 执行文件目录指定创建工程git02创建本地仓库并提交项目
- 一个Java程序的执行要经过编译和执行(解释)这两个步骤,同时Java又是面向对象的编程语言。当子类和父类存在同一个方法,子类重写了父类的方
- 在Spring Cloud 的Feign组件中并不支持文件的传输,会出现这样的错误提示:feign.codec.EncodeExceptio
- 一、整合原理二、导包(41个)1.hibernate(1)hibernate/lib/required(2)hibernate/lib/jp
- 前言最近写了一篇博客是关于 使用Jenkins来构建SVN+Maven项目 ,这里使用的的代码版本工具是SVN,但是事实上也有很多公司使用G
- 前言当用户向服务器发送了一次HTTP请求,该请求可能会经过多个信息资源处理以后才返回给用户,各个信息资源使用请求转发机制相互转发请求,但是用
- 前言Docker旨在提供一种应用程序的自动化部署解决方案,在 Linux 系统上迅速创建一个容器(轻量级虚拟机)并部署和运行应用程序,并通过
- 1.会话会话: 用户打开了一个浏览器,点击了很多超链接,访问多个web次元,关闭浏览器,这个过程可以称之为会话有状态会话: 带有访问记录的会
- Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,
- 1. 为什么要使用线程池使用线程池通常由以下两个原因:频繁创建销毁线程需要消耗系统资源,使用线程池可以复用线程。使用线程池可以更容易管理线程
- 1. 每个编译单元(文件)都只能有一个public类。即每个编译单元都有单一的公共接口,用public类实现。此时,mian()就必须要包含
- 自定义工具类PropertyUtil,并在该类的static静态代码块中读取properties文件内容保存在static属性中以供别的程序
- 本文实例为大家分享了java实现文件下载的具体代码,供大家参考,具体内容如下public HttpServletResponse downl