您的位置:首页 > 其它

WinForm中使用GDI+实现滚动动画

2010-04-24 00:42 211 查看
  前两天有人问用.NET怎么做类似于心电图的图像控件。我以前也从来没做过,但是感觉应该不是很困难,关键是要知道从哪开始下手。所以当时只是讲了下我的初步想法。

  1.心电图显示的是线,而线则是由多个点组成,所以做这个效果实际上就是画点。

  2.要画点,首先就需要设置参考坐标系,然后根据指定坐标来画点。

  3.静态的点画好之后就要实现动态的效果了,也就是随着时间的推移,将所有的点往一个横向方向上移动,然后在最后面空出地方再补充上新的点。不过这里要注意的是,我们看到的仅仅只是显示区域的点,对于已经移出视野的那些点就可以抛弃了,不然越积越多,内存就要爆了。

  昨天晚上没什么事,就想自己动手实践一下,看看理论与实际之间是否存在很大的差距。

  首先,存放这么多个点需要一个容器,由于显示区域的宽度并没有固定,所以这个容器的容量应该是动态的,比如List<T>。但在初步设想时,我就已经想到了在增加新点的同时,要将不需要的点都去掉,而实现这个功能的首选就是泛型队列(Queue<T>)。当然,如果直接使用它,还是存在三个问题:1.队列是不限制容量的;2.队列不会在容量达到设定的上限时自动弹出多余的元素;3.队列不会自动改变点的横坐标,使点动起来。当然,这些问题都可以使用外部方法解决,但如果能在里面解决,使代码更清晰,不是更好吗?

  基于以上三个原因,我选择了从Queue<T>中派生出一个新类PQueue。对于点,本来在写这篇随便的时候,想简化代码,直接使用System.Drawing.Point结构,后来发现结构是值类型的,在foreach(Point p in PQueue){}的内嵌代码中是不能修改它的属性的,而Queue<T>又没有索引器,连for循环也没法使用。所以最后还是创建了一个类似于Point结构的P类。

public class P
{
public int X { get; set; }
public int Y { get; set; }
}


    public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
img = new Img(pic.Width, pic.Height, Color.Black, Color.White);
System.Timers.Timer timer = new System.Timers.Timer(50);
timer.Enabled = true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
}

private Img img;
private int num = 20;
private int i = 1;

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
img.Draw(num);
pic.Image = img.Image;
num = num + i;
if (40 == num)
i = -1;
if (10 == num)
i = 1;
}
}


  运行一下,最后可以看到一条运动的波浪线。以上代码仅仅只是实现了最简单的动画效果,其实只要在改造一下,就可以弄成像迅雷等下载工具的悬浮窗的速度显示效果了。

  注:以上代码需要以下引用命名空间:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: