WPF 大数据加载过程中的等待效果——圆圈转动

摘要:
int_ currentElementIndex=0;int_ opacityCount;double_minOpacity;对象[]_元素;/摘要>私人画布;_opacityCount=(int)(_elementCount*0.5);对于(inti=0;_elementCount;rect.RadiusY=2;如果(i<

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

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

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

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

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

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

WPF 大数据加载过程中的等待效果——圆圈转动第1张WPF 大数据加载过程中的等待效果——圆圈转动第2张
        /// <summary>
        /// 条的数量
        /// </summary>
        int _elementCount;

        /// <summary>
        /// 圆的半径
      /// </summary>
        double _radious = 10;

        /// <summary>
        /// 执行动画的DispatcherTimer
        /// </summary>
        DispatcherTimer _animationTimer;

        /// <summary>
        /// 当前条的索引位置
        /// </summary>
        int _currentElementIndex = 0;

        /// <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;
View Code

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

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

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

WPF 大数据加载过程中的等待效果——圆圈转动第1张WPF 大数据加载过程中的等待效果——圆圈转动第4张
  private void CreateElements(Canvas canvas, double Left, double Top)
        {
            _elementCount = 12;
            _opacity = 1;
            _minOpacity = 0.3;
            double surplusOpacity = _opacity - _minOpacity;
            _opacityCount = (int)(_elementCount * 0.5);
            _opacityInterval = surplusOpacity / _opacityCount;

            _elements = new object[_elementCount];

            for (int i = 0; i < _elementCount; i++)
            {
                Rectangle rect = new Rectangle();
                rect.Fill = new SolidColorBrush(Colors.Black);
                rect.Width = 5;
                rect.Height = 5;
                rect.RadiusX = 2;
                rect.RadiusY = 2;
                if (i < _opacityCount)
                {
                    rect.Opacity = _opacity - i * _opacityInterval;
                }
                else
                {
                    rect.Opacity = _minOpacity;
                }
                rect.SetValue(Canvas.LeftProperty, Left + _radious * Math.Cos(360 / _elementCount * i * Math.PI / 180));
                rect.SetValue(Canvas.TopProperty, Top - 2.5 - _radious * Math.Sin(360 / _elementCount * i * Math.PI / 180));

                rect.RenderTransform = new RotateTransform(360 - 360 / _elementCount * i, 0, 2.5);
                canvas.Children.Add(rect);

                _elements[i] = rect;
            }

            _currentElementIndex = 0;

        }
View Code

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

WPF 大数据加载过程中的等待效果——圆圈转动第1张WPF 大数据加载过程中的等待效果——圆圈转动第6张
 private void _animationTimer_Tick(object sender, EventArgs e)
        {
            try
            {
                _currentElementIndex--;
                _currentElementIndex = _currentElementIndex < 0 ? _elements.Length - 1 : _currentElementIndex;
                int opacitiedCount = 0;
                for (int i = _currentElementIndex; i < _currentElementIndex + _elementCount; i++)
                {
                    int j = i > _elements.Length - 1 ? i - _elements.Length : i;

                    if (opacitiedCount < _opacityCount)
                    {
                        ((Rectangle)_elements[j]).Opacity = _opacity - opacitiedCount * _opacityInterval;
                        opacitiedCount++;
                    }
                    else
                    {
                        ((Rectangle)_elements[j]).Opacity = _minOpacity;
                    }
                }
            }
            catch (Exception ex)
            { }
        }
View Code

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

WPF 大数据加载过程中的等待效果——圆圈转动第1张WPF 大数据加载过程中的等待效果——圆圈转动第8张
        public BusyDecorator(Canvas canvas)
        {
            this._canvas = canvas;
            _animationTimer = new DispatcherTimer();
            _animationTimer.Interval = TimeSpan.FromMilliseconds(40);
            _animationTimer.Tick += new EventHandler(_animationTimer_Tick);

            CreateElements(canvas, canvas.Width / 2, canvas.Height / 2);
        }
View Code

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

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

WPF 大数据加载过程中的等待效果——圆圈转动第1张WPF 大数据加载过程中的等待效果——圆圈转动第10张
        public void StartDecorator()
        {
            _canvas.Visibility = Visibility.Visible;
            _animationTimer.Start();
        }

        public void StopDecorator()
        {
            _canvas.Visibility = Visibility.Hidden;
            _animationTimer.Stop();
        }
View Code

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

做一个前台页面:

WPF 大数据加载过程中的等待效果——圆圈转动第1张WPF 大数据加载过程中的等待效果——圆圈转动第12张
<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>
View Code

后台代码:

WPF 大数据加载过程中的等待效果——圆圈转动第1张WPF 大数据加载过程中的等待效果——圆圈转动第14张
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 = "开始";
            }
        }
    }
}
View Code

静态效果图:

WPF 大数据加载过程中的等待效果——圆圈转动第15张

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

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

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

  

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

  

免责声明:文章转载自《WPF 大数据加载过程中的等待效果——圆圈转动》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇pycharm安装插件的方法Goland安装与配置下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

QT信号槽详解

1         QT信号槽详解 1.1  信号和槽的定义 信号是触发信号,例如按钮的点击触发一个clicked信号,槽是用来接收信号,并处理信号,相当于信号响应函数。一个信号可以关联多个槽函数,信号也可以连接信号。 要使用信号槽,类必须继承与QObject类或者其子类,否则无法识别槽函数错误。在类的定义开头需要添加宏定义Q_OBJECT。如下 clas...

ftp的主动模式(port)与被动模式(PASV) (转)

FTP是仅基于TCP的服务,不支持UDP。与众不同的是FTP使用2个端口,一个数据端口和一个命令端口(也可叫做控制端口)。通常来说这两个端口是21(命令端口)和20(数据端口)。但FTP工作方式的不同,数据端口并不总是20。这就是主动与被动FTP的最大不同之处。  (一)主动FTP           主动方式的FTP是这样的:客户端从一个任意的非特权端口...

java 调用webservice的各种方法总结

java 调用webservice的各种方法总结(本文转自:http://www.blogjava.net/zjhiphop/archive/2009/04/29/webservice.html) 现在webservice加xml技术已经逐渐成熟,但要真正要用起来还需时日!! 由于毕业设计缘故,我看了很多关于webservice方面的知识,今天和大家一...

unity中使用VideoPalyer播放本地视频

using System; using UnityEngine; using System.Collections; using System.Collections.Generic; using System.IO; using UnityEngine.Video; using UnityEngine.UI; using TMPro; using UIW...

C语言集锦(三)Direct3D和GDI+的例子

0.前言   有些时候你可能想了解,如何用纯C语言来写Direct3D和GDI+的Demo。注意,下面的Direct3D例子不适用于TCC编译器,GDI+的例子是可以的。 1.Direct3D C语言的例子   几乎所有的D3D例子都是用COM和C++写的。C语言可以用D3D吗,StackOverflow上给出了答案:directx-programming...

微信小程序的网络设置,及网络请求:wx.request(OBJECT)

微信公众号“颜家大少” 本文所用排版工具:http://md.aclickall.com 微信小程序要实现网络请求,首先要对其进行设置,下面以"微信web开发者工具V1.01.170913"为例 一:对于服务器网站没有备案,或只需要做本地测试的用户 在“微信web开发者工具”的“设置”->“项目设置”->“项目设置”中选:不校验安全域名、TL...