C#自定义UserControl绘制动态波形图详解
在C#开发Windows Forms应用时,有时需要展示随时间变化的连续数据(如心率、传感器读数等)。通过创建自定义 UserControl 并重写绘图逻辑,可以灵活实现轻量级的动态波形图,无需引入第三方庞大库。
实现思路与准备
该控件的核心原理是利用 System.Windows.Forms.Timer 触发重绘事件,在每次绘制周期内更新数据点数组,并使用 Graphics 对象将网格线(背景)和折线图(前景)绘制到屏幕上。由于涉及内存操作,需注意窗口大小改变时的数据数组适配。
关键步骤解析
第1步:定义基础属性与画刷
首先需要声明用于控制界面表现的私有变量和公共属性。这包括背景网格颜色 LINEPEN、前景线条颜色 FORELINEPEN、模拟数据的抖动幅度 shake 以及当前数值 Value。
- SIZE: 定义网格单元的大小,影响视觉密度。
- oldLine数组: 用于存储历史数据点的高度值,配合索引实现滚动效果。
- 属性封装: 使用
[DefaultValue]等特性允许设计器修改Shake(抖动率)、Value(当前值)和LinePen(背景画笔),并在值改变时调用Invalidate()强制刷新。
第2步:实现定时器驱动的数据更新
添加一个Timer控件(文中设为50ms间隔),其 Tick 事件负责推进滚动偏移量并触发界面刷新。
private void timer1_Tick(object sender, EventArgs e)
{
// limits 用于控制垂直网格的滚动偏移
limits++;
if (limits >= SIZE) { limits = 0; }
// 触发 Paint 事件进行重绘
this.Invalidate();
}
第3步:绘制网格背景
在 UserControl1_Paint 事件中,首先遍历横纵坐标,使用 g.DrawLine 绘制背景网格线。注意在横向循环中引入 limits 变量以产生向左滚动的视觉效果。
int h = (int)(this.Size.Height / SIZE);
int w = (int)(this.Size.Width / SIZE) + 1;
// 绘制水平线
for (; h >= 0; h--)
{
g.DrawLine(LINEPEN, new Point(0, h * SIZE), new Point(this.Size.Width, h * SIZE));
}
// 绘制垂直线(含偏移量 limits)
for (; w >= 0; w--)
{
g.DrawLine(LINEPEN, new Point((w * SIZE) - limits, 0), new Point((w * SIZE) - limits, this.Size.Height));
}
第4步:绘制动态前景波形
这是最核心的部分。在绘制新帧前,先对数据进行随机抖动处理(如果开启了 Shake 模式),然后更新 oldLine 数组:
- 数据更新: 将数组整体左移一位,并将最新计算的
Value放入数组末尾。 - 边界约束: 确保
Value始终保持在 0 到 100 之间。 - 坐标映射: 将 0-100 的数值比例映射为控件高度的像素值,依次连接相邻点形成折线。
// 数据移动与新增
for (int j = 0; j < oldLine.Length - 1; j++)
{
oldLine[j] = oldLine[j + 1];
}
oldLine[oldLine.Length - 1] = Value;
// 绘制连线
for (int i = 0; i < oldLine.Length - 1; i++)
{
// 计算 y 坐标:高度减去对应比例的像素数
float ratio = (float)oldLine[i] / 100f;
int y1 = this.Height - (int)(ratio * this.Height) - 1;
ratio = (float)oldLine[i + 1] / 100f;
int y2 = this.Height - (int)(ratio * this.Height) - 1;
g.DrawLine(FORELINEPEN, new Point(i, y1), new Point(i + 1, y2));
}
第5步:处理窗口缩放异常
当控件宽度发生剧烈变化(Resize)时,原有的 oldLine 数组长度可能与新的显示宽度不匹配。代码中提供了简单的对齐逻辑:
- 若窗口变宽,扩展数组长度。
- 若窗口变窄,裁剪数组长度。
此步骤保证波形不会因布局改变而错位或报错。
完成判断
编译通过后,在工具箱中找到自定义的 UserControl 拖入窗体。设置 Timer 启动,并在业务逻辑中动态修改控件的 Value 属性,即可看到平滑滚动的波形动画。若开启 Shake 属性,波形将呈现自然抖动的模拟信号特征。
以上就是C#自定义控件绘制动态波形图的详细内容,更多关于C# GDI+图形编程的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









