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

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

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

因为怕自己班门弄斧,所以在网上先查了资料,确定很难找到这样的实例才敢拿出来与大家见面。不过确实也找到了一个相似效果的案例,但那位高手用的全是前台实现,而我的前辈是在后台写了一个类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. 开始python学习了

    今晚折腾了半天,终于在mac上把python开发ide搞好了. 本来是打算使用eclipse+pydev的,结果在eclipse marketplace里面搜索到得pydev插件无法安装,一直是提示网 ...

  2. shell中bc expr [ ] (( ))的使用方法

    http://blog.chinaunix.net/uid-20671208-id-3552751.html

  3. tony_iptables_01_linux下IPTABLES配置详解(转)

    如果你的IPTABLES基础知识还不了解,建议先去看看. 开始配置 我们来配置一个filter表的防火墙. (1)查看本机关于IPTABLES的设置情况 [root@tp ~]# iptables - ...

  4. DataGridView 导出到Excel

    #region 导出四个表格到Excel /// <summary> /// 导出四个表格到Excel /// </summary> /// <param name=&q ...

  5. NPOI Excel 单元格背景颜色对照表

    NPOI Excel 单元格颜色对照表,在引用了 NPOI.dll 后可通过 ICellStyle 接口的 FillForegroundColor 属性实现 Excel 单元格的背景色设置,FillP ...

  6. 在VS中添加lib的简单方法

    1.工程---属性---配置属性---VC++ Directories---General---Include Directories:加上头文件存放目录 2.VC中,切换到"解决方案视图& ...

  7. NOIP复赛

    [代码为王] http://www.cnblogs.com/codeisking [洛谷] http://www.luogu.org/ NOIP2015 金币 扫雷游戏 求和 推销员 枚举 数学 优先 ...

  8. oracleclient连oracle库 报System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本

    在iis下发布eworkflow+eform+ebiao的代码,访问oracle的数据库,用oracleClient或者oledb的方式连接,有时会报“System.Data.OracleClient ...

  9. ASP.NET 服务器控件的生命周期

    服务器控件生命周期简介 服务器控件的生命周期是创建服务器控件最重要的概念.作为开发人员,必须对服务器控件生命周期深刻理解.当然,这不是一朝一夕就可以做到的.对于学习控件开发技术的初学者,可以不必掌握得 ...

  10. 扩展 HtmlwebpackPlugin 插入自定义的脚本

    webpack提供了一个如何开发 webpack 插件的介绍,你可以直接访问这里查看,这里提供一个扩展 HtmlWebpackPlugin 的开发实例. 前面我们介绍过 HtmlWebpackPlug ...