大家肯定遇到过或将要遇到加载大数据的时候,如果出现长时间的空白等待,一般人的概念会是:难道卡死了?

作为一个懂技术的挨踢技术,即使你明知道数据量太大正在加载,但是假如看不到任何动静,自己觉得还是一种很不好的体验。

之前做项目的时候有这方面的要求,我的前辈们早已给出了完美的解决方案。最近自己在努力学习,今天拿出来与大家一起分享,我想一定会有帮助的。看过之后大家会佩服我的前辈的,呵呵,好,废话少说,下面开始。

因为怕自己班门弄斧,所以在网上先查了资料,确定很难找到这样的实例才敢拿出来与大家见面。不过确实也找到了一个相似效果的案例,但那位高手用的全是前台实现,而我的前辈是在后台写了一个类BusyDecorator,用起来更加方便。喜欢前台xaml实现的可以去看一下那位高手的代码:http://blog.csdn.net/qqamoon/article/details/7001693 他的代码我没做试验,看他的那个实现效果跟我的是一样的。

我的陋代码又要上台表现了,诸位扶好眼镜框了哈~~

首先我们需要定义一些属性用来保存位置,大小,角度,透明度之类:

        /// <summary>
/// 条的数量
/// </summary>
int _elementCount; /// <summary>
/// 圆的半径
/// </summary>
double _radious = ; /// <summary>
/// 执行动画的DispatcherTimer
/// </summary>
DispatcherTimer _animationTimer; /// <summary>
/// 当前条的索引位置
/// </summary>
int _currentElementIndex = ; /// <summary>
/// 需要变换的透明度个数
/// </summary>
int _opacityCount; /// <summary>
/// 透明度间的间隔
/// </summary>
double _opacityInterval; /// <summary>
/// 透明度
/// </summary>
double _opacity; /// <summary>
/// 最小透明度
/// </summary>
double _minOpacity; /// <summary>
/// 条的数组
/// </summary>
object[] _elements; /// <summary>
/// 画布
/// </summary>
private Canvas _canvas;

由于我们是定义在一个类BusyDecorator里面,所以需要在构造函数里定义最初的静态画布效果。然后利用计时器控制动画的启动与停止。

重点便是静态画布的设计与Timer_Tick事件的实现。

我的前辈给出的静态画布设计如下:

  private void CreateElements(Canvas canvas, double Left, double Top)
{
_elementCount = ;
_opacity = ;
_minOpacity = 0.3;
double surplusOpacity = _opacity - _minOpacity;
_opacityCount = (int)(_elementCount * 0.5);
_opacityInterval = surplusOpacity / _opacityCount; _elements = new object[_elementCount]; for (int i = ; i < _elementCount; i++)
{
Rectangle rect = new Rectangle();
rect.Fill = new SolidColorBrush(Colors.Black);
rect.Width = ;
rect.Height = ;
rect.RadiusX = ;
rect.RadiusY = ;
if (i < _opacityCount)
{
rect.Opacity = _opacity - i * _opacityInterval;
}
else
{
rect.Opacity = _minOpacity;
}
rect.SetValue(Canvas.LeftProperty, Left + _radious * Math.Cos( / _elementCount * i * Math.PI / ));
rect.SetValue(Canvas.TopProperty, Top - 2.5 - _radious * Math.Sin( / _elementCount * i * Math.PI / )); rect.RenderTransform = new RotateTransform( - / _elementCount * i, , 2.5);
canvas.Children.Add(rect); _elements[i] = rect;
} _currentElementIndex = ; }

接下来就是Timer_Tick事件了,一般人想不到这样处理吧:

 private void _animationTimer_Tick(object sender, EventArgs e)
{
try
{
_currentElementIndex--;
_currentElementIndex = _currentElementIndex < ? _elements.Length - : _currentElementIndex;
int opacitiedCount = ;
for (int i = _currentElementIndex; i < _currentElementIndex + _elementCount; i++)
{
int j = i > _elements.Length - ? i - _elements.Length : i; if (opacitiedCount < _opacityCount)
{
((Rectangle)_elements[j]).Opacity = _opacity - opacitiedCount * _opacityInterval;
opacitiedCount++;
}
else
{
((Rectangle)_elements[j]).Opacity = _minOpacity;
}
}
}
catch (Exception ex)
{ }
}

好了,重点结束后就是剩下的构造函数BusyDecorator了:

        public BusyDecorator(Canvas canvas)
{
this._canvas = canvas;
_animationTimer = new DispatcherTimer();
_animationTimer.Interval = TimeSpan.FromMilliseconds();
_animationTimer.Tick += new EventHandler(_animationTimer_Tick); CreateElements(canvas, canvas.Width / , canvas.Height / );
}

注意:此构造函数由于用到了canvas.width和canvas.height,所以,前台定义canvas时一定要设置其width和height属性。

然后是启动动画与停止动画事件:

        public void StartDecorator()
{
_canvas.Visibility = Visibility.Visible;
_animationTimer.Start();
} public void StopDecorator()
{
_canvas.Visibility = Visibility.Hidden;
_animationTimer.Stop();
}

好了,类BusyDecorator设计好了,下面做一个实例测试一下吧:

做一个前台页面:

<Window x:Class="testFlowDocument.zhuanquanFlash"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="zhuanquanFlash" Height="300" Width="300">
<Grid>
<Canvas Name="canvas_bu" Width="200" Height="200" VerticalAlignment="Top" Background="LightBlue"> </Canvas>
<Button Name="btn_start" Content="开始" Height="50" VerticalAlignment="Bottom" Click="Button_Click" /> </Grid>
</Window>

后台代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes; namespace testFlowDocument
{
/// <summary>
/// zhuanquanFlash.xaml 的交互逻辑
/// </summary>
public partial class zhuanquanFlash : Window
{
public zhuanquanFlash()
{
InitializeComponent();
busy = new BusyDecorator(this.canvas_bu);
}
BusyDecorator busy;
bool isstart = false;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (isstart == false)
{
busy.StartDecorator();
isstart = true;
this.btn_start.Content = "停止";
}
else
{
busy.StopDecorator();
isstart = false;
this.btn_start.Content = "开始";
}
}
}
}

静态效果图:

PS:如何快速制作动态gif图?像上边链接地址里的那样的gif图。不会photoshop,求推荐好使工具~~

本文地址:http://www.cnblogs.com/jying/p/3230391.html  转载请写明出处~~

ok,到此为止,谢谢大家捧场~~

个人小站欢迎来踩:驾校教练评价平台 | 为爱豆砌照片墙

WPF 大数据加载过程中的等待效果——圆圈转动的更多相关文章

  1. [Aaronyang] 写给自己的WPF4.5 笔记6[三巴掌-大数据加载与WPF4.5 验证体系详解 2/3]

    我要做回自己--Aaronyang的博客(www.ayjs.net) 博客摘要: Virtualizing虚拟化DEMO 和 大数据加载的思路及相关知识 WPF数据提供者的使用ObjectDataPr ...

  2. asp.net中TreeView的大数据加载速度优化

    由于数据量太大,加载树时间很长,所以进行了优化 前台 .aspx <asp:Panel ID="Panel2" runat="server" Height ...

  3. DOM加载过程中ready和load的区别

    在浏览器地址栏输入URL地址,浏览器开始加载页面时,有以下几个过程 1.浏览器开始解析HTML文档 2. 浏览器遇到HTML文档中的<script>元素以及CSS样式文件,并且没有asyn ...

  4. DevExpress ChartControl大数据加载时有哪些性能优化方法

    DevExpress ChartControl加载大数据量数据时的性能优化方法有哪些? 关于图表优化,可从以下几个方面解决: 1.关闭不需要的可视化的元素(如LineMarkers, Labels等) ...

  5. css3实现loading效果--当页面加载过程中显示Loading的进度条,全部加载完成之后进度条消失

    一个页面等图片资源全部加载完成,会需要很长时间,用户体验会很差,所以我们需要loading来掩盖这个漫长的过程! emmm,定时器?写个定时器还要清除,万一造成内存泄露?定时器之间还会互相影响,呼呼呼 ...

  6. iOS学习之视图加载过程中会触发的方法(loadView/viewDidLoad/didReceiveMemoryWarning)

    1.loadView 这是视图控制器用来加载根视图的方法; 如果需要将自定义的视图作为根视图,则不需要调用父类对该方法的实现([super loadView]);直接将自定义视图通过self.view ...

  7. spring加载过程中jar包加载不了,解决方法

    当我们在开发spring项目时,一般会将jar包放到webInf/lib下,这样是myeclipse自动将jar包加载到tomcat中webapps下,但是当我们新建一个lib文件夹的情况下,我们ad ...

  8. 在程序加载过程中显示ProgressDialog 对话框

    private ProgressDialog mProgressDlg = null; @Override protected void onCreate(Bundle savedInstanceSt ...

  9. 输入 URL 到页面完成加载过程中的所有发生的事情?

    转到浏览器中输入URL给你一个页面后,.有些事情,你每天都在使用,学的是计算机网络知道是怎么回事.DNS解析然后页面的回馈,只是要讲好还是有难度. 之前fex团队的nwind专门写过这个问题的博客: ...

随机推荐

  1. MVC图片上传

    HTML代码: <form method="post" enctype="multipart/form-data"> 上传图片:<input ...

  2. android studio 使用ndk编译.C文件生成so文件

    task buildSo(type: Exec) { //windows commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePat ...

  3. oracle11g dataguard 完全手册

    一.前言: 网络上关于dataguard的配置文章很多,但是很多打着oracle11g的文章实际都是只能在9 10 上运行,比如FAL_CLIENT在11g中已经废弃,但是现在网络上的文章都是没有标注 ...

  4. Git——2

    什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改.删除,Git都能跟踪,以便任何时刻都可以追踪历史,或 ...

  5. test spring in category

    test tile package com.journaldev.spring.controller; import java.text.DateFormat; import java.util.Da ...

  6. Fail2ban 防止暴力破解centos服务器的SSH或者FTP账户

    次尝试登陆root账户失败的情况.[说明服务器被攻击了]   logtarget = SYSLOG  #我们需要做的就是把这行改成/var/log/fail2ban.log,方便用来记录日志信息 so ...

  7. sqlserver获取数据库表结构

    SqlServer获取所有数据库,表,表结构 --获取所有数据库 SELECT * FROM Master..SysDatabases ORDER BY Name --获取test数据库下所有表 us ...

  8. 在MyBook Live上部署svn

    一直以来都在用svn管理源代码,美中不足的是由于svn服务器端部署在本地,无法实现在异地迁入迁出程序,因此考虑将svn服务器部署在我的MyBook Live上. 一.部署svn 1.分别执行以下2条命 ...

  9. Nopcommerce 二次开发2 WEB

    using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel.Syndica ...

  10. 线程Thread

    一.线程: 程序:保存在物理介质(光盘,软盘,硬盘)当中的代码片段 进程:一旦程序运行起来,就变成了操作系统当中的一个进程 线程:程序当中一条独立执行的线索 二.线程的五大状态 新生    就绪 运行 ...