野比的示波器案例(Winfrom用户控件)

发布于:2021-06-15 19:34:34

使用该用户控件做的效果图,如果数据正确,可实现 波形、直线、等等效果图。。。。。。




?


对于本程序的认识还是不够深彻。如果有其他方法或算法,欢迎讨论下。将我所能理解的代码都再次标识了一番。


?


?


--------------------------------------------------------------------------------------------------using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace PowerTest
{
??? public partial class StatusChart : UserControl
??? {

??????? #region ** 私有成员:属性 **
??????? ///


??????? /// 波形所容纳的最大值
??????? ///

??????? private int range = 100;?
??????? ///
??????? /// 定时器间隔
??????? ///

??????? private int interval = 1;
??????? ///
??????? /// Chart 值数组
??????? ///

??????? private int[] val;
??????? ///
??????? /// 当前值
??????? ///

??????? private int currentValue = 0;
??????? ///
??????? /// W:画布宽度 ,H:画布高度
??????? ///

??????? private int w, h;
??????? ///
??????? /// 定时器
??????? ///

??????? private Timer tmrRefresh;


??????? ///


??????? /// 私有成员:绘图? 绘图方式
??????? ///

??????? private ChartMode chartMode = ChartMode.Waveform;???
??????? ///
??????? /// *移偏移量
??????? ///

??????? private int iOffset = 0;
??????? ///
??????? /// 网格是否*移
??????? ///

??????? private bool gridShiftting = true;
??????? ///
??????? /// 网格*移间距
??????? ///

??????? private int gridShifttingIncrement = 1;
??????? ///
??????? /// 网格宽度
??????? ///

??????? private int gridWidth = 10;
??????? ///
??????? /// 网格高度
??????? ///

??????? private int gridHeight = 10;
??????? ///
??????? /// 绘制网格画笔
??????? ///

??????? private Pen penChart = new Pen(Color.Lime, 2);
??????? ///
??????? /// 绘制曲线画笔
??????? ///

??????? private Pen penGrid = new Pen(Color.Green);
??????? ///
??????? /// 魔版
??????? ///

??????? private Graphics graph;


??????? #endregion


??????? #region ** 私有方法:绘制图形 **
??????? ///


??????? /// 根据画布大小绘制所需求大小的网格
??????? ///

??????? /// 魔板
??????? /// 网格每次*移变量
??????? private void DrawGrids(ref Graphics g, int 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 + 1;
??????????? pos = 0F;
??????????? //循环画竖线
??????????? for (int i = 0; i < (int)div; i++)
??????????? {
??????????????? g.DrawLine(penGrid, 0, pos, w, pos);
??????????????? pos += gridHeight;
??????????? }
??????? }



??????? ///
??????? /// 魔板
??????? /// 画笔
??????? /// 数据数组
??????? {
??????????? //从 0 到 w 绘制
??????????? int len = w;
??????????? //根据绘制方式(多重阴影与单线)
??????????? if (chartMode == StatusChart.ChartMode.Histogram)
??????????? {
??????????????? //绘制的是数据A点与画布高度之间的连线
??????????????? //绘制第一个数据,一直到,倒数第二个数据
??????????????? for (int i = 0; i < len; i++)
??????????????? {


??????????????????? //第一个点(i,画布高度减去第i个数据),第二个点(i,画布高度)
??????????????????? g.DrawLine(p, i, h - val[i], i, h);
??????????????? }
??????????????? //第一个点(画布宽度,画布宽度减去最后一个数据),第二个点(画布宽度,画布高度)
??????????????? g.DrawLine(p, len, h - val[len - 1], len, h);
??????????? }
??????????? else
??????????? {
??????????????? len--;
??????????????? //绘制的是一条数据A点与数据B点的连线
??????????????? //绘制第一个数据,一直到,倒数第二个数据之间每一个点的连线
??????????????? for (int i = 0; i < len; i++)
??????????????? {
??????????????????? //两点决定1向量
??????????????????? //第一个点(i,画布高度减去第i个数据),第二个点(i+1,画布高度减去第i+1个数据)
??????????????????? g.DrawLine(p, i, h - val[i], i + 1, h - val[i + 1]);
??????????????? }
??????????????? len++;
??????????????? //绘制倒数第二个与最后一个数据之间的连线(绘制最后两个点之间的连线)
??????????????? //第一个点(画布宽度-1,画布宽度减去倒数第二个数据),第二个点(画布宽度,画布宽带减去倒数第一个数据)
??????????????? g.DrawLine(p, len - 1, h - val[len - 2], len, h - val[len - 1]);
??????????? }
??????? }


?


??????? ///


??????? /// 私有方法:重写方法系统? OnLoad? 方法? (窗体加载事件)
??????? ///

??????? ///
??????? protected override void OnLoad(EventArgs e)
??????? {


??????????? //base.OnLoad(e);
??????????? //打开双缓冲(双缓存),防止闪烁
??????????? DoubleBuffered = true;
??????????? h = base.ClientSize.Height - 1;
??????????? w = base.ClientSize.Width - 1;
??????????? val = new int[w];
??????????? //创建一个 Timer 控件
??????????? tmrRefresh = new Timer();
??????????? //设置Timer时间
??????????? tmrRefresh.Interval = interval;
??????????? //开始Timer
??????????? tmrRefresh.Enabled = true;
??????????? //绑定事件
??????????? tmrRefresh.Tick += new EventHandler(tmrRefresh_Tick);


??????? }



??????? ///


??????? /// 重写改变窗体大小事件
??????? ///

??????? ///
??????? protected override void OnResize(EventArgs e)
??????? {
??????????? h = base.ClientSize.Height;
??????????? w = base.ClientSize.Width;
??????????? Array.Resize(ref val, w);
??????????? //使控件的整个图面无效并导致重绘控件。(导致OnPaint事件的发生)
??????????? Invalidate();
??????? }


?


??????? ///


??????? /// 控件重写,重新绘制事件(由系统控制,每秒不知道重绘N次)
??????? ///

??????? ///
??????? protected override void OnPaint(PaintEventArgs e)
??????? {
??????????? //base.OnPaint(e);
??????????? graph = e.Graphics;
??????????? DrawGrids(ref graph, iOffset);
??????????? DrawChart(ref graph, penChart, ref? val);
??????? }


??????? ///


??????? /// 定时器更新(由tmrRefresh定时器绑定的方法)
??????? ///

??????? ///
??????? ///
??????? private void tmrRefresh_Tick(object sender, EventArgs e)
??????? {


??????????? //(难点)
??????????? //只有启用了网格移动才处理
??????????? {
??????????????? iOffset += gridShifttingIncrement;
??????????????? iOffset %= gridWidth;
??????????? }
??????????? //更新图形(整体左移)
??????????? //必须在这里而不能在画图的同时移动,
??????????? //若在画图中移动,则当画面被遮挡(OnPaint)事件不发生时无法更新
??????????? int len = w;


??????????? //不断的将数组中的第i个位置的数据移动到第i-1的位置。
??????????? 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;


??????????? //使控件的整个图面无效并导致重绘控件。(导致OnPaint事件的发生)
??????????? Invalidate();
??????? }


??????? #endregion



??????? #region ** 公共成员:设置绘制方式(多重阴影与单线) **
??????? ///


??????? /// 波形图显示方式枚举。
??????? ///

??????? public enum ChartMode
??????? {
??????????? ///
??????????? /// 直方图
??????????? ///

??????????? Histogram = 0,??? //直方图
??????????? ///
??????????? /// 波形图
??????????? ///

??????????? Waveform??????? //波形图
??????? }
??????? #endregion


??????? #region ** 公共属性 **
??????? //指定一个属性或事件是否应显示在“属性”窗口中。
??????? [Browsable(true)]


??????? ///


??????? /// 当前值(给的数据,外面用一个Timer来每多少毫秒给一次数据,对外的Timer要与本StatusChart用户控件中的Timer时间同步)。
??????? ///

??????? [Category("内容"), Description("当前值。"), DefaultValue(0)]
??????? public int Value
??????? {
??????????? get
??????????? {
??????????????? return currentValue;
??????????? }
??????????? set
??????????? {
??????????????? //约束 value
??????????????? if (value > range)
??????????????? {
??????????????????? value = range;
??????????????? }
??????????????? if (value < 0)
??????????????? {
??????????????????? value = 0;
??????????????? }
??????????????? //根据 Range 属性修正 value
??????????????? //尽量减小误差
??????????????? value = (int)((float)value / (float)range * (float)h);
??????????????? currentValue = value;
??????????? }
??????? }
??????? ///
??????? /// 数据值范围。绘图时将根据此值缩放 Value 值。
??????? ///

??????? [Category("内容"), Description("数据值范围。绘图时将根据此值缩放 Value 值。"), DefaultValue(100)]
??????? public int Range
??????? {
??????????? get
??????????? {
??????????????? return range;
??????????? }
??????????? set
??????????? {
??????????????? range = value;
??????????? }
??????? }
??????? ///
??????? /// 波形图刷新间隔。
??????? ///

??????? [Category("内容"), Description("波形图刷新间隔。"), DefaultValue(500)]
??????? public int Interval
??????? {
??????????? get
??????????? {
??????????????? return interval;
??????????? }
??????????? set
??????????? {
??????????????? interval = value;
??????????????? if (tmrRefresh != null)
??????????????? {
??????????????????? tmrRefresh.Interval = interval;
??????????????? }
??????????? }
??????? }
??????? ///
??????? /// 指示波形是否继续更新。
??????? ///

??????? [Category("内容"), Description("指示波形是否继续更新。"), DefaultValue(true)]
??????? public new bool Enabled
??????? {
??????????? get
??????????? {
??????????????? if (tmrRefresh != null)
??????????????? {
??????????????????? return tmrRefresh.Enabled;
??????????????? }
??????????????? else
??????????????? {
??????????????????? return false;
??????????????? }
??????????? }
??????????? set
??????????? {
??????????????? if (tmrRefresh != null)
??????????????? {
??????????????????? tmrRefresh.Enabled = value;
??????????????? }
??????????? }
??????? }
??????? ///
??????? /// 显示方式。
??????? ///

??????? [Category("外观"), Description("波形显示方式。"), DefaultValue(typeof(StatusChart.ChartMode), "Histogram")]
??????? public ChartMode Mode
??????? {
??????????? get
??????????? {
??????????????? return chartMode;
??????????? }
??????????? set
??????????? {
??????????????? chartMode = value;
??????????? }
??????? }
??????? ///
??????? /// 网格每次更新时向左*移的距离。
??????? ///

??????? [Category("外观"), Description("网格每次更新时向左*移的距离。"), DefaultValue(1)]
??????? public int ShifttingIncrement
??????? {
??????????? get
??????????? {
??????????????? return gridShifttingIncrement;
??????????? }
??????????? set
??????????? {
??????????????? gridShifttingIncrement = value;
??????????????? if (gridShifttingIncrement < 0)
??????????????? {
??????????????????? gridShifttingIncrement = 0;
??????????????? }
??????????? }
??????? }
??????? ///
??????? /// 指示网格是否每次更新时向左*移。
??????? ///

??????? [Category("外观"), Description("指示网格是否每次更新时向左*移。"), DefaultValue(true)]
??????? public bool GridShiftting
??????? {
??????????? get
??????????? {
??????????????? return gridShiftting;
??????????? }
??????????? set
??????????? {
??????????????? gridShiftting = value;
??????????? }
??????? }
??????? ///
??????? /// 网格宽度。
??????? ///

??????? [Category("外观"), Description("网格宽度。"), DefaultValue(10)]
??????? public int GridWidth
??????? {
??????????? get
??????????? {
??????????????? return gridWidth;
??????????? }
??????????? set
??????????? {
??????????????? gridWidth = value;
??????????????? Invalidate();
??????????? }
??????? }
??????? ///
??????? /// 网格高度。
??????? ///

??????? [Category("外观"), Description("网格高度。"), DefaultValue(10)]
??????? public int GridHeight
??????? {
??????????? get
??????????? {
??????????????? return gridHeight;
??????????? }
??????????? set
??????????? {
??????????????? gridHeight = value;
??????????????? Invalidate();
??????????? }
??????? }
??????? ///
??????? /// 网格颜色。
??????? ///

??????? [Category("外观"), Description("网格颜色。"), DefaultValue(typeof(Color), "Green")]
??????? public Color GridColor
??????? {
??????????? get
??????????? {
??????????????? return penGrid.Color;
??????????? }
??????????? set
??????????? {
??????????????? penGrid.Color = value;
??????????? }
??????? }
??????? ///
??????? /// 波形颜色。
??????? ///

??????? [Category("外观"), Description("波形颜色。"), DefaultValue(typeof(Color), "Lime")]
??????? public override Color ForeColor
??????? {
??????????? get
??????????? {
??????????????? return penChart.Color;
??????????? }
??????????? set
??????????? {
??????????????? penChart.Color = value;
??????????? }
??????? }
??????? #endregion



??????? #region ** 公共方法 **
??????? ///


??????? /// 启动计时器更新。返回执行情况。
??????? ///

??????? /// 执行情况。true 成功;false 失败。
??????? public bool Start()
??????? {
??????????? try
??????????? {
??????????????? if (tmrRefresh != null)
??????????????? {
??????????????????? tmrRefresh.Enabled = true;
??????????????????? return true;
??????????????? }
??????????????? else
??????????????? {
??????????????????? return false;
??????????????? }
??????????? }
??????????? catch
??????????? {
??????????????? return false;
??????????? }
??????? }
??????? ///
??????? /// 停止计时器更新。返回执行情况。
??????? ///

??????? /// 执行情况。true 成功;false 失败。
??????? public bool Stop()
??????? {
??????????? try
??????????? {
??????????????? if (tmrRefresh != null)
??????????????? {
??????????????????? tmrRefresh.Enabled = false;
??????????????????? return true;
??????????????? }
??????????????? else
??????????????? {
??????????????????? return false;
??????????????? }
??????????? }
??????????? catch
??????????? {
??????????????? return false;
??????????? }
??????? }
??????? ///
??????? /// 清除历史状态记录。
??????? ///

??????? public void Clear()
??????? {
??????????? if (val != null)
??????????? {
??????????????? //没用
??????????????? //val.Initialize();
??????????????? Array.Resize(ref val, 0);
??????????????? Array.Resize(ref val, w);
??????????????? currentValue = 0;
??????????? }
??????? }
??????? ///
??????? /// 控制计时器更新。返回执行情况。
??????? ///

??????? /// 执行情况。true 成功;false 失败。
??????? public void StopTrim(bool bol)
??????? {
??????????? tmrRefresh.Enabled = bol;
??????? }



??????? #endregion


??? }
}
?


?


--------------------------------------------------------------------------------------------------使用该用户控件做的效果图,如果数据正确,可实现波形、直线、等等效果图 。。。。。。




?


----------------------对于本程序的认识还是不够深彻。如果有其他方法或算法,欢迎讨论下。将我所能理解的代码都再次标识了一番。


?




http://yunpan.cn/Q7YT8FGMMgn5x ?提取码 6cc8



http://yunpan.cn/Q7YTkEHm24cJD ?提取码 3cb8





DotNetBar9.2.0.0*獍,去除了AdvTree的Trial信息:


http://yunpan.cn/Q7YTGgegJS9LW ?提取码 8143







转载于:https://www.cnblogs.com/xulang/p/5506186.html






相关资源:示波器控件(.NET)

相关推荐

最新更新

猜你喜欢