「控件控」高仿快车、迅雷、Windows、地震仪多用途状态波形图

Conmajia 2012-05-07 01:16:03
加精
熬夜看韩剧的人伤不起啊。。

中场休息,闲来无事把以前的老货在论坛存个档

------------中场休息线------------------

原发:bccn.net [April, 2008]

原题:Nobi's StatusChart - 野比的状态波形图控件 从构思到实现

老规矩,DEMO 和源码 (时隔多年,链接和图片不保证还有效)


点击下载 DEMO

点击下载源码


Nobi's StatusChart - 野比的状态波形图控件

从构思到实现

野比 著

背景

目前比较流行的 WinForm 程序设计都会提供形象的可视化数据流动记录功能,

如 FlashGet 及其衍生软件的悬浮窗网速监视图,Windows 任务管理器的 CPU、内存使用图等。





构思

为了在我们自己的程序中实现这种效果,就需要研究、分析它们的原理,掌握其规律,然后加以实现。很明显,从软件可重用性以及各种随之而来的好处考虑,我们要求将这个“波形显示”效果做成一个控件(Control)。

分析

还是以 FlashGet 的悬浮窗和 Windows 任务管理器作为研究对象。仔细观察它们的工作方式,发现它们有以下的共同点:



在右边更新当前的波形值
更新后的波形不消失,而是整体向左平移
可以设置波形颜色、更新速度等

而通过深入研究,发现二者不同点如下:



不同的显示方式,有曲线显示和直方图显示
有无定位网格
各部分颜色可自定义


设计

通过分析,可以决定如下:凡是二者共同点,加以重点实现;凡二者不同之处,通过设置属性(Property)进行更改。最后绘制时,基于所设置的属性,使用共同方法加以实现。
因此自定义属性如下:



BackColor(重写基类属性)
Enabled(重写)
ForeColor(重写)
GridColor 网格颜色
GridHeight 网格每格高度
GridShiftting 是否平移网格
GridWidth 网格每格宽度
Interval 波形刷新间隔(单位:毫秒)
Mode 波形显示方式(曲线/直方图)
Range 数值范围
ShifttingIncrement 向左平移增量
Value 当前值

控件因为要定时更新,因此具有一个内部的 Timer 对其进行定时,其 Interval 由控件的 Interval 属性指定。
对于此自定义控件,需要每次更新时在其 OnPaint() 事件中对整个控件进行绘制。绘制顺序为:背景 - 网格 - 波形,如此保证所有部分均正确画出且无遮挡。
从波形看,很明显,我们需要一个长度至少等于波形控件宽度的数组来存放每时刻波形的值,因此可以确定这个数组是和控件绘图画布宽度一致的。

算法

绘图最重要的是算法部分,如何计算如网格位置,如何将图形整体平移,如何设置波形值是本控件的重点和难点部分。
计算网格位置,以上面的 ShifttingIncrement 为 offset 参数传入


            //网格数(不计边缘)
float div;
float pos = 0F;
//先画 垂直 方向
//可以少画一根线
div = (float)w / (float)gridWidth + 1;
for (int i = 0; i < (int)div; i++)
{
pos += gridWidth;
g.DrawLine(penGrid, pos - offset, 0, pos - offset, h);
}
//画 水平 方向
div = (float)h / (float)gridHeight;
pos = 0F;
for (int i = 0; i < (int)div; i++)
{
pos += gridHeight;
g.DrawLine(penGrid, 0, pos, w, pos);
}




对于波形,传入其波形值数组作为参数

            //从 0 到 w 绘制
int len = w;
//根据绘制方式
if (chartMode == StatusChart.ChartMode.Histogram)
{
for (int i = 0; i < len; i++)
{
g.DrawLine(p, i, h - val[i], i, h);
}
g.DrawLine(p, len, h - val[len - 1], len, h);
}
else
{
len--;
for (int i = 0; i < len; i++)
{
g.DrawLine(p, i, h - val[i], i + 1, h - val[i + 1]);
}
len++;
g.DrawLine(p, len - 1, h - val[len - 2], len, h - val[len - 1]);
}




如何平移,是一个难点,需要在内部定时器的 Tick() 事件中加以处理

            //更新网格偏移
//只有启用了网格移动才处理
if (gridShiftting)
{
iOffset += gridShifttingIncrement;
iOffset %= gridWidth;
}
//更新图形(整体左移)
//必须在这里而不能在画图的同时移动,
//若在画图中移动,则当画面被遮挡(OnPaint)事件不发生时无法更新
int len = w;
for (int i = 0; i < len; i++)
{
//判断数组越界
if (i < len - 1)
{
val[i] = val[i + 1];
}
else
{
val[len - 1] = currentValue;
//break;
}
}
//val[len] = currentValue;
Invalidate();



最后引发控件的 Invalidate() 方法使控件重绘自身。

效果

最后的控件运行效果如下图所示:(用的随机数做数据,所以感觉乱跳)






声明

本控件仅供,学习交流,请勿用于商业用途或其他一切正式场合。
作者野比拒绝对因擅用本控件所造成的一切法律或社会的不良后果负责。
For evaluation ONLY, NOT for commercial use!

如果你的程序用到了本控件或其部分思路,请发一份给我,让我也能分享到你的成就!


---------下半场开始-------

继续韩剧。。。
...全文
6462 97 打赏 收藏 转发到动态 举报
写回复
用AI写文章
97 条回复
切换为时间正序
请发表友善的回复…
发表回复
u010421705 2013-04-24
  • 打赏
  • 举报
回复
这段时间正在制作这方面的东西,值得参考,谢谢楼主~~~
httpwrong 2013-04-13
  • 打赏
  • 举报
回复
我也下来试试看,感谢楼主
leafmao 2013-04-11
  • 打赏
  • 举报
回复
照着LZ的例子学习学习
u010197225 2013-04-11
  • 打赏
  • 举报
回复
强大 很强大
zqg20529 2013-03-30
  • 打赏
  • 举报
回复
虽然是模仿的,但是做得很不错,顶一个!
pf79102576 2012-12-02
  • 打赏
  • 举报
回复
使用全身力气顶一下
yojinlin 2012-06-17
  • 打赏
  • 举报
回复
感謝分享。
ff252361 2012-06-17
  • 打赏
  • 举报
回复
分享有利于共同进步!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
落曦 2012-06-15
  • 打赏
  • 举报
回复
楼主是清华计算机系毕业的吧。我已经把你看穿了。呜呜。
猴头 2012-06-10
  • 打赏
  • 举报
回复
源码和离子下载不了,给个新的连接吧
  • 打赏
  • 举报
回复
控件控
lfqsy 2012-06-01
  • 打赏
  • 举报
回复
好像我以前就下载过他的,不过被我搞的面目全非了
yangfaning 2012-05-31
  • 打赏
  • 举报
回复
看贴总是不回 ,一直没提升等级和增加经验,现在我明白了,反正回贴可以升级 ,也可以赚经验,而升级又需要经验 ,我就把这句话复制下来,遇贴就灌水,捞到经验就闪。
aspnetdev 2012-05-28
  • 打赏
  • 举报
回复
这么老的帖挖出来还用得着吗?
Conmajia 2012-05-28
  • 打赏
  • 举报
回复
[Quote=引用 79 楼 的回复:]

bccn注册不了啊
老是说cookie有问题
[/Quote]

网上搜吧,大把转载的
huwenfeng2001hf 2012-05-28
  • 打赏
  • 举报
回复
这控件是不错,收藏
caoqinghua 2012-05-28
  • 打赏
  • 举报
回复
哈哈,挖....
--reply by CSDN Study V1.0.0.3 (starts_2000)
comana 2012-05-16
  • 打赏
  • 举报
回复
bccn注册不了啊
老是说cookie有问题
满CD的程序猿 2012-05-16
  • 打赏
  • 举报
回复
羡慕、嫉妒、恨....
Conmajia 2012-05-14
  • 打赏
  • 举报
回复
回头看看总觉得算法有问题。
加载更多回复(51)

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧