当前位置: 首页 > news >正文

如何做网站超链接图片外链上传网站

如何做网站超链接,图片外链上传网站,进行网站建设的上市公司,网站做多个页面本代码调用ZedGraph绘图框架,自己先安装好ZedGraph环境,然后拖一个zedGraphControl控件就行了,直接黏贴下面代码 基本代码显示 using System; using System.Windows.Forms; using ZedGraph; using System.Timers;namespace ECGPlot {public…

本代码调用ZedGraph绘图框架,自己先安装好ZedGraph环境,然后拖一个zedGraphControl控件就行了,直接黏贴下面代码

基本代码显示

using System;
using System.Windows.Forms;
using ZedGraph;
using System.Timers;namespace ECGPlot
{public partial class Form1 : Form{// 定义导联数量和每个导联的电压偏移量private const int ChannelCount = 8;private const int VoltageOffset = 150; // 每个导联的偏移量// 用于存储每个导联的数据点列表和曲线对象private PointPairList[] _dataLists;private LineItem[] _curves;// 定时器用于模拟ECG信号数据更新private System.Timers.Timer _timer;private int _currentIndex = 0;private int _maxPoints = 500;private double[][] _yValues;private double _timeIncrement = 0.1;private double _currentTime = 0;private Random _random = new Random();public Form1(){InitializeComponent();InitializeGraph(); // 初始化图表StartTimer(); // 启动定时器}private void InitializeGraph(){// 获取图表区域对象GraphPane myPane = zedGraphControl1.GraphPane;// 设置图表标题和轴标题myPane.Title.Text = "ECG Data";myPane.XAxis.Title.Text = "Time";myPane.YAxis.Title.Text = "Voltage";// 初始化数据点列表和曲线数组_dataLists = new PointPairList[ChannelCount];_curves = new LineItem[ChannelCount];_yValues = new double[ChannelCount][];for (int i = 0; i < ChannelCount; i++){// 为每个导联创建数据点列表和曲线对象,并添加到图表中_dataLists[i] = new PointPairList();_curves[i] = myPane.AddCurve($"ECG Channel {i + 1}", _dataLists[i], GetColor(i), SymbolType.None);_yValues[i] = new double[_maxPoints];}// 设置X轴和Y轴的范围myPane.XAxis.Scale.Min = 0;myPane.XAxis.Scale.Max = _maxPoints * _timeIncrement;myPane.YAxis.Scale.Min = -600;myPane.YAxis.Scale.Max = 600 + VoltageOffset * (ChannelCount - 1);// 显示网格线myPane.XAxis.MajorGrid.IsVisible = true;myPane.YAxis.MajorGrid.IsVisible = true;// 应用更改并刷新图表zedGraphControl1.AxisChange();}private System.Drawing.Color GetColor(int index){// 定义一组颜色用于不同导联的曲线System.Drawing.Color[] colors = {System.Drawing.Color.Black,System.Drawing.Color.Red,System.Drawing.Color.Blue,System.Drawing.Color.Green,System.Drawing.Color.Purple,System.Drawing.Color.Orange,System.Drawing.Color.Brown,System.Drawing.Color.Magenta};// 根据索引返回颜色return colors[index % colors.Length];}private void StartTimer(){// 创建并配置定时器_timer = new System.Timers.Timer(100); // 100毫秒的更新频率_timer.Elapsed += OnTimedEvent; // 绑定定时器事件_timer.AutoReset = true; // 自动重置_timer.Enabled = true; // 启用定时器}private void OnTimedEvent(Object source, ElapsedEventArgs e){// 为每个导联生成模拟ECG信号数据并更新曲线for (int i = 0; i < ChannelCount; i++){double voltage = _random.Next(-400, 400) + i * VoltageOffset; // 生成带偏移量的电压数据_yValues[i][_currentIndex] = voltage;if (_dataLists[i].Count < _maxPoints){// 添加新的数据点_dataLists[i].Add(_currentTime, voltage);}else{// 更新现有数据点_dataLists[i][_currentIndex].Y = voltage;}}// 更新时间和当前索引_currentTime += _timeIncrement;_currentIndex = (_currentIndex + 1) % _maxPoints;// 使图表无效以触发重绘zedGraphControl1.Invalidate();}private void Form1_Load(object sender, EventArgs e){// 窗体加载事件处理方法(目前为空)}}
}

注释解释:

  1. 全局变量定义:定义导联数量、每个导联的电压偏移量,以及存储数据和曲线的变量。
  2. 构造函数:调用 InitializeGraphStartTimer 方法初始化图表和启动定时器。
  3. InitializeGraph 方法:初始化图表区域,设置标题和轴标题,创建每个导联的曲线对象,并设置轴的范围和网格。
  4. GetColor 方法:定义一组颜色,根据索引返回颜色用于不同导联的曲线。
  5. StartTimer 方法:创建并配置定时器,设置定时器事件处理方法。
  6. OnTimedEvent 方法:在定时器触发时生成模拟ECG信号数据,为每个导联添加或更新数据点,并刷新图表。
  7. Form1_Load 方法:窗体加载事件处理方法(目前为空)。

在这里插入图片描述

添加了y轴方向的导联标签

using System;
using System.Windows.Forms;
using ZedGraph;
using System.Timers;namespace ECGPlot
{public partial class Form1 : Form{// 定义导联数量和每个导联的电压偏移量private const int ChannelCount = 8;private const int VoltageOffset = 500; // 每个导联的偏移量// 用于存储每个导联的数据点列表和曲线对象private PointPairList[] _dataLists;private LineItem[] _curves;// 定时器用于模拟ECG信号数据更新private System.Timers.Timer _timer;private int _currentIndex = 0;private int _maxPoints = 500;private double[][] _yValues;private double _timeIncrement = 0.1;private double _currentTime = 0;private Random _random = new Random();public Form1(){InitializeComponent();InitializeGraph(); // 初始化图表StartTimer(); // 启动定时器}private void InitializeGraph(){// 获取图表区域对象GraphPane myPane = zedGraphControl1.GraphPane;// 设置图表标题和轴标题myPane.Title.Text = "ECG Data";myPane.XAxis.Title.Text = "Time (s)";myPane.YAxis.Title.Text = "Voltage";// 初始化数据点列表和曲线数组_dataLists = new PointPairList[ChannelCount];_curves = new LineItem[ChannelCount];_yValues = new double[ChannelCount][];for (int i = 0; i < ChannelCount; i++){// 为每个导联创建数据点列表和曲线对象,并添加到图表中_dataLists[i] = new PointPairList();_curves[i] = myPane.AddCurve("", _dataLists[i], GetColor(i), SymbolType.None);_yValues[i] = new double[_maxPoints];}// 移除图例myPane.Legend.IsVisible = false;// 设置X轴和Y轴的范围myPane.XAxis.Scale.Min = 0;myPane.XAxis.Scale.Max = _maxPoints * _timeIncrement;myPane.YAxis.Scale.Min = -800;myPane.YAxis.Scale.Max = 800 + VoltageOffset * (ChannelCount - 1);// 显示网格线myPane.XAxis.MajorGrid.IsVisible = true;myPane.YAxis.MajorGrid.IsVisible = true;// 隐藏Y=0的实线myPane.YAxis.MajorGrid.IsZeroLine = false;// 自定义Y轴刻度标注Scale yScale = myPane.YAxis.Scale;yScale.MajorStep = VoltageOffset;yScale.MinorStep = VoltageOffset;yScale.MajorStepAuto = false;yScale.MinorStepAuto = false;myPane.YAxis.ScaleFormatEvent += new Axis.ScaleFormatHandler(FormatYScale);// 应用更改并刷新图表zedGraphControl1.AxisChange();}private string FormatYScale(GraphPane pane, Axis axis, double val, int index){// 自定义Y轴刻度标注int leadIndex = (int)Math.Round(val / VoltageOffset);if (leadIndex >= 0 && leadIndex < ChannelCount){return $"Lead {leadIndex + 1}";}return "";}private System.Drawing.Color GetColor(int index){// 定义一组颜色用于不同导联的曲线System.Drawing.Color[] colors = {System.Drawing.Color.Black,System.Drawing.Color.Red,System.Drawing.Color.Blue,System.Drawing.Color.Green,System.Drawing.Color.Purple,System.Drawing.Color.Orange,System.Drawing.Color.Brown,System.Drawing.Color.Magenta};// 根据索引返回颜色return colors[index % colors.Length];}private void StartTimer(){// 创建并配置定时器_timer = new System.Timers.Timer(10); // 100毫秒的更新频率_timer.Elapsed += OnTimedEvent; // 绑定定时器事件_timer.AutoReset = true; // 自动重置_timer.Enabled = true; // 启用定时器}private void OnTimedEvent(Object source, ElapsedEventArgs e){// 为每个导联生成模拟ECG信号数据并更新曲线for (int i = 0; i < ChannelCount; i++){double voltage = _random.Next(-200, 200) + i * VoltageOffset; // 生成带偏移量的电压数据_yValues[i][_currentIndex] = voltage;if (_dataLists[i].Count < _maxPoints){// 添加新的数据点_dataLists[i].Add(_currentTime, voltage);}else{// 更新现有数据点_dataLists[i][_currentIndex].Y = voltage;}}// 更新时间和当前索引_currentTime += _timeIncrement;_currentIndex = (_currentIndex + 1) % _maxPoints;// 更新X轴刻度显示zedGraphControl1.GraphPane.XAxis.Scale.TextLabels = GenerateTimeLabels(_currentTime, _timeIncrement, _maxPoints);// 使图表无效以触发重绘zedGraphControl1.Invalidate();}private string[] GenerateTimeLabels(double currentTime, double increment, int maxPoints){string[] labels = new string[maxPoints];double startTime = currentTime - (maxPoints * increment);for (int i = 0; i < maxPoints; i++){labels[i] = (startTime + i * increment).ToString("0.0");}return labels;}private void Form1_Load(object sender, EventArgs e){// 窗体加载事件处理方法(目前为空)}}
}

在这里插入图片描述

添加了时间刻度跟随时间扫描变化

using System;
using System.Windows.Forms;
using ZedGraph;
using System.Timers;namespace ECGPlot
{public partial class Form1 : Form{// 定义导联数量和每个导联的电压偏移量private const int ChannelCount = 8;private const int VoltageOffset = 700; // 每个导联的偏移量// 用于存储每个导联的数据点列表和曲线对象private PointPairList[] _dataLists;private LineItem[] _curves;// 定时器用于模拟ECG信号数据更新private System.Timers.Timer _timer;private int _currentIndex = 0;private int _maxPoints = 800;private double[][] _yValues;private double _timeIncrement = 0.1;private double _currentTime = 0;private Random _random = new Random();private DateTime[] _timeLabels;public Form1(){InitializeComponent();InitializeGraph(); // 初始化图表StartTimer(); // 启动定时器}private void InitializeGraph(){// 获取图表区域对象GraphPane myPane = zedGraphControl1.GraphPane;// 设置图表标题和轴标题myPane.Title.Text = "ECG Data";myPane.XAxis.Title.Text = "Time";myPane.YAxis.Title.Text = "Voltage";// 初始化数据点列表和曲线数组_dataLists = new PointPairList[ChannelCount];_curves = new LineItem[ChannelCount];_yValues = new double[ChannelCount][];_timeLabels = new DateTime[_maxPoints];for (int i = 0; i < ChannelCount; i++){// 为每个导联创建数据点列表和曲线对象,并添加到图表中_dataLists[i] = new PointPairList();_curves[i] = myPane.AddCurve("", _dataLists[i], GetColor(i), SymbolType.None);_yValues[i] = new double[_maxPoints];}// 移除图例myPane.Legend.IsVisible = false;// 设置X轴和Y轴的范围myPane.XAxis.Scale.Min = 0;myPane.XAxis.Scale.Max = _maxPoints;myPane.YAxis.Scale.Min = -800;myPane.YAxis.Scale.Max = 800 + VoltageOffset * (ChannelCount - 1);// 显示网格线myPane.XAxis.MajorGrid.IsVisible = true;myPane.YAxis.MajorGrid.IsVisible = true;// 隐藏Y=0的实线myPane.YAxis.MajorGrid.IsZeroLine = false;// 自定义Y轴刻度标注Scale yScale = myPane.YAxis.Scale;yScale.MajorStep = VoltageOffset;yScale.MinorStep = VoltageOffset;yScale.MajorStepAuto = false;yScale.MinorStepAuto = false;myPane.YAxis.ScaleFormatEvent += new Axis.ScaleFormatHandler(FormatYScale);// 设置X轴为文本类型myPane.XAxis.Type = AxisType.Text;// 设置X轴刻度字体大小myPane.XAxis.Scale.FontSpec.Size = 7; // 可以根据需要调整字体大小myPane.XAxis.Scale.FontSpec.FontColor = System.Drawing.Color.Black;// 初始化时间标签DateTime startTime = DateTime.Now;for (int i = 0; i < _maxPoints; i++){_timeLabels[i] = startTime;}// 应用更改并刷新图表zedGraphControl1.AxisChange();}private string FormatYScale(GraphPane pane, Axis axis, double val, int index){// 自定义Y轴刻度标注int leadIndex = (int)Math.Round(val / VoltageOffset);if (leadIndex >= 0 && leadIndex < ChannelCount){return $"Lead {leadIndex + 1}";}return "";}private System.Drawing.Color GetColor(int index){// 定义一组颜色用于不同导联的曲线System.Drawing.Color[] colors = {//System.Drawing.Color.Black,//System.Drawing.Color.Red,//System.Drawing.Color.Blue,//System.Drawing.Color.Green,//System.Drawing.Color.Purple,//System.Drawing.Color.Orange,//System.Drawing.Color.Brown,//System.Drawing.Color.MagentaSystem.Drawing.Color.Black,System.Drawing.Color.Black,System.Drawing.Color.Black,System.Drawing.Color.Black,System.Drawing.Color.Black,System.Drawing.Color.Black,System.Drawing.Color.Black,System.Drawing.Color.Black};// 根据索引返回颜色return colors[index % colors.Length];}private void StartTimer(){// 创建并配置定时器_timer = new System.Timers.Timer(1); // 100毫秒的更新频率_timer.Elapsed += OnTimedEvent; // 绑定定时器事件_timer.AutoReset = true; // 自动重置_timer.Enabled = true; // 启用定时器}private void OnTimedEvent(Object source, ElapsedEventArgs e){// 记录当前时间DateTime currentTime = DateTime.Now;// 为每个导联生成模拟ECG信号数据并更新曲线for (int i = 0; i < ChannelCount; i++){double voltage = _random.Next(-200, 200) + i * VoltageOffset; // 生成带偏移量的电压数据_yValues[i][_currentIndex] = voltage;if (_dataLists[i].Count < _maxPoints){// 添加新的数据点_dataLists[i].Add(_currentIndex, voltage);}else{// 更新现有数据点_dataLists[i][_currentIndex].Y = voltage;}}// 更新时间标签_timeLabels[_currentIndex] = currentTime;// 更新时间和当前索引_currentTime += _timeIncrement;_currentIndex = (_currentIndex + 1) % _maxPoints;// 更新X轴刻度显示zedGraphControl1.GraphPane.XAxis.Scale.TextLabels = GenerateTimeLabels();// 使图表无效以触发重绘zedGraphControl1.Invalidate();}private string[] GenerateTimeLabels(){string[] labels = new string[_maxPoints];for (int i = 0; i < _maxPoints; i++){labels[i] = _timeLabels[i].ToString("HH:mm:ss.fff");}return labels;}private void Form1_Load(object sender, EventArgs e){// 窗体加载事件处理方法(目前为空)}}
}

在这里插入图片描述

添加了个竖线,扫描分界线

using System;
using System.Windows.Forms;
using ZedGraph;
using System.Timers;namespace ECGPlot
{public partial class Form1 : Form{// 定义导联数量和每个导联的电压偏移量private const int ChannelCount = 8;private const int VoltageOffset = 500; // 每个导联的偏移量// 用于存储每个导联的数据点列表和曲线对象private PointPairList[] _dataLists;private LineItem[] _curves;// 定时器用于模拟ECG信号数据更新private System.Timers.Timer _timer;private int _currentIndex = 0;private int _maxPoints = 500;private double[][] _yValues;private double _timeIncrement = 0.1;private double _currentTime = 0;private Random _random = new Random();private DateTime[] _timeLabels;private LineObj _scanLine;public Form1(){InitializeComponent();InitializeGraph(); // 初始化图表StartTimer(); // 启动定时器}private void InitializeGraph(){// 获取图表区域对象GraphPane myPane = zedGraphControl1.GraphPane;// 设置图表标题和轴标题myPane.Title.Text = "ECG Data";myPane.XAxis.Title.Text = "Time (hh:mm:ss.fff)";myPane.YAxis.Title.Text = "Voltage";// 初始化数据点列表和曲线数组_dataLists = new PointPairList[ChannelCount];_curves = new LineItem[ChannelCount];_yValues = new double[ChannelCount][];_timeLabels = new DateTime[_maxPoints];for (int i = 0; i < ChannelCount; i++){// 为每个导联创建数据点列表和曲线对象,并添加到图表中_dataLists[i] = new PointPairList();_curves[i] = myPane.AddCurve("", _dataLists[i], GetColor(i), SymbolType.None);_yValues[i] = new double[_maxPoints];}// 移除图例myPane.Legend.IsVisible = false;// 设置X轴和Y轴的范围myPane.XAxis.Scale.Min = 0;myPane.XAxis.Scale.Max = _maxPoints;myPane.YAxis.Scale.Min = -800;myPane.YAxis.Scale.Max = 800 + VoltageOffset * (ChannelCount - 1);// 显示网格线myPane.XAxis.MajorGrid.IsVisible = true;myPane.YAxis.MajorGrid.IsVisible = true;// 隐藏Y=0的实线myPane.YAxis.MajorGrid.IsZeroLine = false;// 自定义Y轴刻度标注Scale yScale = myPane.YAxis.Scale;yScale.MajorStep = VoltageOffset;yScale.MinorStep = VoltageOffset;yScale.MajorStepAuto = false;yScale.MinorStepAuto = false;myPane.YAxis.ScaleFormatEvent += new Axis.ScaleFormatHandler(FormatYScale);// 设置X轴为文本类型myPane.XAxis.Type = AxisType.Text;// 设置X轴刻度字体大小myPane.XAxis.Scale.FontSpec.Size = 10; // 可以根据需要调整字体大小// 初始化时间标签DateTime startTime = DateTime.Now;for (int i = 0; i < _maxPoints; i++){_timeLabels[i] = startTime;}// 初始化扫描竖线_scanLine = new LineObj(System.Drawing.Color.Black, 0, -800, 0, 800 + VoltageOffset * (ChannelCount - 1));_scanLine.Line.Style = System.Drawing.Drawing2D.DashStyle.Dash;_scanLine.IsClippedToChartRect = true;myPane.GraphObjList.Add(_scanLine);// 应用更改并刷新图表zedGraphControl1.AxisChange();}private string FormatYScale(GraphPane pane, Axis axis, double val, int index){// 自定义Y轴刻度标注int leadIndex = (int)Math.Round(val / VoltageOffset);if (leadIndex >= 0 && leadIndex < ChannelCount){return $"Lead {leadIndex + 1}";}return "";}private System.Drawing.Color GetColor(int index){// 定义一组颜色用于不同导联的曲线System.Drawing.Color[] colors = {System.Drawing.Color.Gray,System.Drawing.Color.Gray,System.Drawing.Color.Gray,System.Drawing.Color.Gray,System.Drawing.Color.Gray,System.Drawing.Color.Gray,System.Drawing.Color.Gray,System.Drawing.Color.Gray,};// 根据索引返回颜色return colors[index % colors.Length];}private void StartTimer(){// 创建并配置定时器_timer = new System.Timers.Timer(50); // 100毫秒的更新频率_timer.Elapsed += OnTimedEvent; // 绑定定时器事件_timer.AutoReset = true; // 自动重置_timer.Enabled = true; // 启用定时器}private void OnTimedEvent(Object source, ElapsedEventArgs e){// 记录当前时间DateTime currentTime = DateTime.Now;// 为每个导联生成模拟ECG信号数据并更新曲线for (int i = 0; i < ChannelCount; i++){double voltage = _random.Next(-200, 200) + i * VoltageOffset; // 生成带偏移量的电压数据_yValues[i][_currentIndex] = voltage;if (_dataLists[i].Count < _maxPoints){// 添加新的数据点_dataLists[i].Add(_currentIndex, voltage);}else{// 更新现有数据点_dataLists[i][_currentIndex].Y = voltage;}}// 更新时间标签_timeLabels[_currentIndex] = currentTime;// 更新时间和当前索引_currentTime += _timeIncrement;_currentIndex = (_currentIndex + 1) % _maxPoints;// 更新X轴刻度显示zedGraphControl1.GraphPane.XAxis.Scale.TextLabels = GenerateTimeLabels();// 更新扫描竖线位置UpdateScanLine();// 使图表无效以触发重绘zedGraphControl1.Invalidate();}private string[] GenerateTimeLabels(){string[] labels = new string[_maxPoints];for (int i = 0; i < _maxPoints; i++){labels[i] = _timeLabels[i].ToString("HH:mm:ss.fff");}return labels;}private void UpdateScanLine(){// 移除旧的扫描竖线zedGraphControl1.GraphPane.GraphObjList.Remove(_scanLine);// 添加新的扫描竖线_scanLine = new LineObj(System.Drawing.Color.Black, _currentIndex, -800, _currentIndex, 800 + VoltageOffset * (ChannelCount - 1));_scanLine.Line.Style = System.Drawing.Drawing2D.DashStyle.Dash;_scanLine.IsClippedToChartRect = true;zedGraphControl1.GraphPane.GraphObjList.Add(_scanLine);// 应用更改并刷新图表zedGraphControl1.AxisChange();}private void Form1_Load(object sender, EventArgs e){// 窗体加载事件处理方法(目前为空)}}
}

在这里插入图片描述

我修改了扫描线左边和右边是不同颜色

using System;
using System.Windows.Forms;
using ZedGraph;
using System.Timers;namespace ECGPlot
{public partial class Form1 : Form{// 定义导联数量和每个导联的电压偏移量private const int ChannelCount = 8;private const int VoltageOffset = 500; // 每个导联的偏移量// 用于存储每个导联的数据点列表和曲线对象private PointPairList[] _dataListsLeft;private PointPairList[] _dataListsRight;private LineItem[] _curvesLeft;private LineItem[] _curvesRight;// 定时器用于模拟ECG信号数据更新private System.Timers.Timer _timer;private int _currentIndex = 0;private int _maxPoints = 500;private double[][] _yValues;private double _timeIncrement = 0.1;private double _currentTime = 0;private Random _random = new Random();private DateTime[] _timeLabels;private LineObj _scanLine;public Form1(){InitializeComponent();InitializeGraph(); // 初始化图表StartTimer(); // 启动定时器}private void InitializeGraph(){// 获取图表区域对象GraphPane myPane = zedGraphControl1.GraphPane;// 设置图表标题和轴标题myPane.Title.Text = "ECG Data";myPane.XAxis.Title.Text = "Time";myPane.YAxis.Title.Text = "Voltage";// 初始化数据点列表和曲线数组_dataListsLeft = new PointPairList[ChannelCount];_dataListsRight = new PointPairList[ChannelCount];_curvesLeft = new LineItem[ChannelCount];_curvesRight = new LineItem[ChannelCount];_yValues = new double[ChannelCount][];_timeLabels = new DateTime[_maxPoints];for (int i = 0; i < ChannelCount; i++){// 为每个导联创建数据点列表和曲线对象,并添加到图表中_dataListsLeft[i] = new PointPairList();_dataListsRight[i] = new PointPairList();_curvesLeft[i] = myPane.AddCurve("", _dataListsLeft[i], System.Drawing.Color.Black, SymbolType.None);_curvesRight[i] = myPane.AddCurve("", _dataListsRight[i], System.Drawing.ColorTranslator.FromHtml("#CCCCCC"), SymbolType.None);_yValues[i] = new double[_maxPoints];// 初始化右边灰色波形for (int j = 0; j < _maxPoints; j++){_dataListsRight[i].Add(j, double.NaN); // 初始化为NaN,表示没有数据}}// 移除图例myPane.Legend.IsVisible = false;// 设置X轴和Y轴的范围myPane.XAxis.Scale.Min = 0;myPane.XAxis.Scale.Max = _maxPoints;myPane.YAxis.Scale.Min = -800;myPane.YAxis.Scale.Max = 800 + VoltageOffset * (ChannelCount - 1);// 显示网格线myPane.XAxis.MajorGrid.IsVisible = true;myPane.YAxis.MajorGrid.IsVisible = true;// 隐藏Y=0的实线myPane.YAxis.MajorGrid.IsZeroLine = false;// 自定义Y轴刻度标注Scale yScale = myPane.YAxis.Scale;yScale.MajorStep = VoltageOffset;yScale.MinorStep = VoltageOffset;yScale.MajorStepAuto = false;yScale.MinorStepAuto = false;myPane.YAxis.ScaleFormatEvent += new Axis.ScaleFormatHandler(FormatYScale);// 设置X轴为文本类型myPane.XAxis.Type = AxisType.Text;// 设置X轴刻度字体大小myPane.XAxis.Scale.FontSpec.Size = 4; // 可以根据需要调整字体大小// 初始化时间标签DateTime startTime = DateTime.Now;for (int i = 0; i < _maxPoints; i++){_timeLabels[i] = startTime;}// 初始化扫描竖线_scanLine = new LineObj(System.Drawing.Color.Black, 0, -800, 0, 800 + VoltageOffset * (ChannelCount - 1));_scanLine.Line.Style = System.Drawing.Drawing2D.DashStyle.Dash;_scanLine.IsClippedToChartRect = true;myPane.GraphObjList.Add(_scanLine);// 应用更改并刷新图表zedGraphControl1.AxisChange();}private string FormatYScale(GraphPane pane, Axis axis, double val, int index){// 自定义Y轴刻度标注int leadIndex = (int)Math.Round(val / VoltageOffset);if (leadIndex >= 0 && leadIndex < ChannelCount){return $"Lead {leadIndex + 1}";}return "";}private void StartTimer(){// 创建并配置定时器_timer = new System.Timers.Timer(50); // 50毫秒的更新频率_timer.Elapsed += OnTimedEvent; // 绑定定时器事件_timer.AutoReset = true; // 自动重置_timer.Enabled = true; // 启用定时器}private void OnTimedEvent(Object source, ElapsedEventArgs e){// 记录当前时间DateTime currentTime = DateTime.Now;// 为每个导联生成模拟ECG信号数据并更新曲线for (int i = 0; i < ChannelCount; i++){double voltage = _random.Next(-200, 200) + i * VoltageOffset; // 生成带偏移量的电压数据_yValues[i][_currentIndex] = voltage;if (_dataListsLeft[i].Count < _maxPoints){// 添加新的数据点_dataListsLeft[i].Add(_currentIndex, voltage);}else{// 更新现有数据点_dataListsLeft[i][_currentIndex].Y = voltage;}// 更新右边灰色波形数据点_dataListsRight[i][_currentIndex].Y = voltage;}// 更新时间标签_timeLabels[_currentIndex] = currentTime;// 更新时间和当前索引_currentTime += _timeIncrement;_currentIndex = (_currentIndex + 1) % _maxPoints;// 更新曲线数据UpdateCurves();// 更新X轴刻度显示zedGraphControl1.GraphPane.XAxis.Scale.TextLabels = GenerateTimeLabels();// 更新扫描竖线位置UpdateScanLine();// 使图表无效以触发重绘zedGraphControl1.Invalidate();}private void UpdateCurves(){for (int i = 0; i < ChannelCount; i++){// 更新左边(黑色)部分PointPairList leftPoints = _curvesLeft[i].Points as PointPairList;leftPoints.Clear();for (int j = 0; j < _maxPoints; j++){if (j <= _currentIndex){leftPoints.Add(j, _yValues[i][j]);}else{leftPoints.Add(j, double.NaN);}}}}private string[] GenerateTimeLabels(){string[] labels = new string[_maxPoints];for (int i = 0; i < _maxPoints; i++){labels[i] = _timeLabels[i].ToString("HH:mm:ss.fff");}return labels;}private void UpdateScanLine(){// 移除旧的扫描竖线zedGraphControl1.GraphPane.GraphObjList.Remove(_scanLine);// 添加新的扫描竖线_scanLine = new LineObj(System.Drawing.Color.Black, _currentIndex, -800, _currentIndex, 800 + VoltageOffset * (ChannelCount - 1));_scanLine.Line.Style = System.Drawing.Drawing2D.DashStyle.Dash;_scanLine.IsClippedToChartRect = true;zedGraphControl1.GraphPane.GraphObjList.Add(_scanLine);// 应用更改并刷新图表zedGraphControl1.AxisChange();}private void Form1_Load(object sender, EventArgs e){// 窗体加载事件处理方法(目前为空)}}
}

在这里插入图片描述

第一次扫描时间刻度的设置

using System;
using System.Windows.Forms;
using ZedGraph;
using System.Timers;
using System.Drawing;
using System.IO;namespace ECGPlot
{public partial class Form1 : Form{// 定义导联数量和每个导联的电压偏移量private const int ChannelCount = 8;private const int VoltageOffset = 500; // 每个导联的偏移量// 用于存储每个导联的数据点列表和曲线对象private PointPairList[] _dataListsLeft;private PointPairList[] _dataListsRight;private LineItem[] _curvesLeft;private LineItem[] _curvesRight;// 定时器用于模拟ECG信号数据更新private System.Timers.Timer _timer;private int _currentIndex = 0;private int _maxPoints = 1000;private double[][] _yValues;private double _timeIncrement = 0.1;private double _currentTime = 0;private Random _random = new Random();private DateTime[] _timeLabels;private LineObj _scanLine;private bool _firstScan = true;public Form1(){InitializeComponent();InitializeGraph(); // 初始化图表InitializeDataFile(); // 初始化数据文件StartTimer(); // 启动定时器}private void InitializeGraph(){// 获取图表区域对象GraphPane myPane = zedGraphControl1.GraphPane;// 设置图表标题和轴标题myPane.Title.Text = "ECG Data";myPane.XAxis.Title.Text = "Time";myPane.YAxis.Title.Text = "Voltage";// 初始化数据点列表和曲线数组_dataListsLeft = new PointPairList[ChannelCount];_dataListsRight = new PointPairList[ChannelCount];_curvesLeft = new LineItem[ChannelCount];_curvesRight = new LineItem[ChannelCount];_yValues = new double[ChannelCount][];_timeLabels = new DateTime[_maxPoints];for (int i = 0; i < ChannelCount; i++){// 为每个导联创建数据点列表和曲线对象,并添加到图表中_dataListsLeft[i] = new PointPairList();_dataListsRight[i] = new PointPairList();_curvesLeft[i] = myPane.AddCurve("", _dataListsLeft[i], System.Drawing.Color.Black, SymbolType.None);_curvesRight[i] = myPane.AddCurve("", _dataListsRight[i], Color.FromArgb(100, Color.Black), SymbolType.None);_yValues[i] = new double[_maxPoints];// 初始化右边灰色波形for (int j = 0; j < _maxPoints; j++){_dataListsRight[i].Add(j, double.NaN); // 初始化为NaN,表示没有数据}}// 移除图例myPane.Legend.IsVisible = false;// 设置X轴和Y轴的范围myPane.XAxis.Scale.Min = 0;myPane.XAxis.Scale.Max = _maxPoints;myPane.YAxis.Scale.Min = -800;myPane.YAxis.Scale.Max = 800 + VoltageOffset * (ChannelCount - 1);// 网格线myPane.XAxis.MajorGrid.IsVisible = false; // 关闭纵向主要网格线myPane.XAxis.MinorGrid.IsVisible = false; // 关闭纵向次要网格线myPane.YAxis.MajorGrid.IsVisible = true;// 隐藏Y=0的实线myPane.YAxis.MajorGrid.IsZeroLine = false;// 自定义Y轴刻度标注Scale yScale = myPane.YAxis.Scale;yScale.MajorStep = VoltageOffset;yScale.MinorStep = VoltageOffset;yScale.MajorStepAuto = false;yScale.MinorStepAuto = false;myPane.YAxis.ScaleFormatEvent += new Axis.ScaleFormatHandler(FormatYScale);myPane.YAxis.Scale.FontSpec.Size = 8;myPane.YAxis.Scale.FontSpec.Family = "Times New Roman"; // 设置字体为// 设置X轴为文本类型myPane.XAxis.Type = AxisType.Text;// 设置X轴刻度字体大小myPane.XAxis.Scale.FontSpec.Size = 5; // 可以根据需要调整字体大小myPane.XAxis.Scale.FontSpec.Family = "Times New Roman"; // 设置字体为// 初始化时间标签DateTime startTime = DateTime.Now;for (int i = 0; i < _maxPoints; i++){_timeLabels[i] = startTime;}// 初始化扫描竖线_scanLine = new LineObj(System.Drawing.Color.Black, 0, -800, 0, 800 + VoltageOffset * (ChannelCount - 1));_scanLine.Line.Style = System.Drawing.Drawing2D.DashStyle.Dash;_scanLine.IsClippedToChartRect = true;myPane.GraphObjList.Add(_scanLine);// 应用更改并刷新图表zedGraphControl1.AxisChange();}private string FormatYScale(GraphPane pane, Axis axis, double val, int index){// 自定义Y轴刻度标注int leadIndex = (int)Math.Round(val / VoltageOffset);if (leadIndex >= 0 && leadIndex < ChannelCount){return $"Lead {leadIndex + 1}";}return "";}private void StartTimer(){// 创建并配置定时器_timer = new System.Timers.Timer(50); // 50毫秒的更新频率_timer.Elapsed += OnTimedEvent; // 绑定定时器事件_timer.AutoReset = true; // 自动重置_timer.Enabled = true; // 启用定时器}private void OnTimedEvent(Object source, ElapsedEventArgs e){// 记录当前时间DateTime currentTime = DateTime.Now;// 为每个导联生成模拟ECG信号数据并更新曲线for (int i = 0; i < ChannelCount; i++){double voltage = _random.Next(-200, 200) + i * VoltageOffset; // 生成带偏移量的电压数据_yValues[i][_currentIndex] = voltage;if (_dataListsLeft[i].Count < _maxPoints){// 添加新的数据点_dataListsLeft[i].Add(_currentIndex, voltage);}else{// 更新现有数据点_dataListsLeft[i][_currentIndex].Y = voltage;}// 更新右边灰色波形数据点_dataListsRight[i][_currentIndex].Y = voltage;}// 更新时间标签_timeLabels[_currentIndex] = currentTime;// 实时保存数据到文件SaveCurrentDataToFile(_currentIndex, currentTime);// 更新时间和当前索引_currentTime += _timeIncrement;_currentIndex = (_currentIndex + 1) % _maxPoints;// 更新曲线数据UpdateCurves();// 更新X轴刻度显示zedGraphControl1.GraphPane.XAxis.Scale.TextLabels = GeneratePartialTimeLabels();// 更新扫描竖线位置UpdateScanLine();// 使图表无效以触发重绘zedGraphControl1.Invalidate();}private void UpdateCurves(){for (int i = 0; i < ChannelCount; i++){// 更新左边(黑色)部分PointPairList leftPoints = _curvesLeft[i].Points as PointPairList;leftPoints.Clear();for (int j = 0; j < _maxPoints; j++){if (j <= _currentIndex){leftPoints.Add(j, _yValues[i][j]);}else{leftPoints.Add(j, double.NaN);}}}}private string[] GeneratePartialTimeLabels(){string[] labels = new string[_maxPoints];for (int i = 0; i < _maxPoints; i++){if (i <= _currentIndex || !_firstScan){labels[i] = _timeLabels[i].ToString("HH:mm:ss.fff");}else{labels[i] = ""; // 未扫描到的位置使用空字符串}}// 仅在第一次扫描后将_firstScan设为falseif (_currentIndex == _maxPoints - 1){_firstScan = false;}return labels;}private void UpdateScanLine(){// 移除旧的扫描竖线zedGraphControl1.GraphPane.GraphObjList.Remove(_scanLine);// 添加新的扫描竖线_scanLine = new LineObj(System.Drawing.Color.Black, _currentIndex, -800, _currentIndex, 800 + VoltageOffset * (ChannelCount - 1));_scanLine.Line.Style = System.Drawing.Drawing2D.DashStyle.Solid;_scanLine.IsClippedToChartRect = true;zedGraphControl1.GraphPane.GraphObjList.Add(_scanLine);// 应用更改并刷新图表zedGraphControl1.AxisChange();}private void SaveCurrentDataToFile(int index, DateTime time){string filePath = "ECGData.txt"; // 可以修改为需要保存的文件路径try{using (StreamWriter writer = new StreamWriter(filePath, true)) // 以追加模式打开文件{// 写入索引writer.Write($"{index},");// 写入8个导联的数据for (int j = 0; j < ChannelCount; j++){writer.Write($"{_yValues[j][index]},");}// 写入时间writer.WriteLine(time.ToString("HH:mm:ss.fff"));}}catch (Exception ex){MessageBox.Show($"Error saving data: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);}}private void InitializeDataFile(){string filePath = "ECGData.txt"; // 可以修改为需要保存的文件路径try{using (StreamWriter writer = new StreamWriter(filePath, false)) // 以覆盖模式打开文件{// 写入表头writer.WriteLine("Index,Lead1,Lead2,Lead3,Lead4,Lead5,Lead6,Lead7,Lead8,Time");}}catch (Exception ex){MessageBox.Show($"Error initializing data file: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);}}private void btnSaveData_Click(object sender, EventArgs e){using (SaveFileDialog saveFileDialog = new SaveFileDialog()){saveFileDialog.Filter = "Text files (*.txt)|*.txt";saveFileDialog.Title = "Save ECG Data";if (saveFileDialog.ShowDialog() == DialogResult.OK){SaveDataToFile(saveFileDialog.FileName);}}}private void SaveDataToFile(string filePath){try{using (StreamWriter writer = new StreamWriter(filePath)){// 写入表头writer.WriteLine("Index,Lead1,Lead2,Lead3,Lead4,Lead5,Lead6,Lead7,Lead8,Time");for (int i = 0; i < _maxPoints; i++){// 写入索引writer.Write($"{i},");// 写入8个导联的数据for (int j = 0; j < ChannelCount; j++){writer.Write($"{_yValues[j][i]},");}// 写入时间writer.WriteLine(_timeLabels[i].ToString("HH:mm:ss.fff"));}}MessageBox.Show("Data saved successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);}catch (Exception ex){MessageBox.Show($"Error saving data: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);}}private void Form1_Load(object sender, EventArgs e){// 窗体加载事件处理方法(目前为空)}}
}

在这里插入图片描述

提高响应速度

在Windows窗体应用程序中使用System.Timers.Timer,其回调在不同于UI线程的线程上运行。如果你要更新UI控件(如ZedGraphControl),最好使用System.Windows.Forms.Timer,因为它在UI线程上执行。下面是你如何改进代码以使用System.Windows.Forms.Timer来避免线程间的调度问题并提高响应速度。
此外,确保图表在更新时不会频繁刷新,这样可以减少卡顿。

修改后的代码

using System;
using System.Windows.Forms;
using ZedGraph;
using System.Drawing;
using System.IO;namespace ECGPlot
{public partial class Form1 : Form{// 定义导联数量和每个导联的电压偏移量private const int ChannelCount = 8;private const int VoltageOffset = 500; // 每个导联的偏移量// 用于存储每个导联的数据点列表和曲线对象private PointPairList[] _dataListsLeft;private PointPairList[] _dataListsRight;private LineItem[] _curvesLeft;private LineItem[] _curvesRight;// 定时器用于模拟ECG信号数据更新private System.Windows.Forms.Timer _timer;private int _currentIndex = 0;private int _maxPoints = 1101;private double[][] _yValues;private double _timeIncrement = 0.1;private double _currentTime = 0;private Random _random = new Random();private DateTime[] _timeLabels;private LineObj _scanLine;private bool _firstScan = true;public Form1(){InitializeComponent();InitializeGraph(); // 初始化图表InitializeDataFile(); // 初始化数据文件StartTimer(); // 启动定时器}private void InitializeGraph(){// 获取图表区域对象GraphPane myPane = zedGraphControl1.GraphPane;// 设置图表标题和轴标题myPane.Title.Text = "ECG Data";myPane.XAxis.Title.Text = "Time";myPane.YAxis.Title.Text = "Voltage";// 初始化数据点列表和曲线数组_dataListsLeft = new PointPairList[ChannelCount];_dataListsRight = new PointPairList[ChannelCount];_curvesLeft = new LineItem[ChannelCount];_curvesRight = new LineItem[ChannelCount];_yValues = new double[ChannelCount][];_timeLabels = new DateTime[_maxPoints];for (int i = 0; i < ChannelCount; i++){// 为每个导联创建数据点列表和曲线对象,并添加到图表中_dataListsLeft[i] = new PointPairList();_dataListsRight[i] = new PointPairList();_curvesLeft[i] = myPane.AddCurve("", _dataListsLeft[i], System.Drawing.Color.Black, SymbolType.None);_curvesRight[i] = myPane.AddCurve("", _dataListsRight[i], Color.FromArgb(100, Color.Black), SymbolType.None);_yValues[i] = new double[_maxPoints];// 初始化右边灰色波形for (int j = 0; j < _maxPoints; j++){_dataListsRight[i].Add(j, double.NaN); // 初始化为NaN,表示没有数据}}// 移除图例myPane.Legend.IsVisible = false;// 设置X轴和Y轴的范围myPane.XAxis.Scale.Min = 0;myPane.XAxis.Scale.Max = _maxPoints;myPane.YAxis.Scale.Min = -800;myPane.YAxis.Scale.Max = 800 + VoltageOffset * (ChannelCount - 1);// 设置X轴主刻度步长,使刻度标签不那么密集myPane.XAxis.Scale.MajorStep = 100; // 可以根据需要调整这个值// 网格线myPane.XAxis.MajorGrid.IsVisible = false; // 关闭纵向主要网格线myPane.XAxis.MinorGrid.IsVisible = false; // 关闭纵向次要网格线myPane.YAxis.MajorGrid.IsVisible = true;// 隐藏Y=0的实线myPane.YAxis.MajorGrid.IsZeroLine = false;// 自定义Y轴刻度标注Scale yScale = myPane.YAxis.Scale;yScale.MajorStep = VoltageOffset;yScale.MinorStep = VoltageOffset;yScale.MajorStepAuto = false;yScale.MinorStepAuto = false;myPane.YAxis.ScaleFormatEvent += new Axis.ScaleFormatHandler(FormatYScale);myPane.YAxis.Scale.FontSpec.Size = 8;myPane.YAxis.Scale.FontSpec.Family = "Times New Roman"; // 设置字体为// 设置X轴为文本类型myPane.XAxis.Type = AxisType.Text;// 设置X轴刻度字体大小myPane.XAxis.Scale.FontSpec.Size = 8; // 可以根据需要调整字体大小myPane.XAxis.Scale.FontSpec.Family = "Times New Roman"; // 设置字体为// 初始化时间标签DateTime startTime = DateTime.Now;for (int i = 0; i < _maxPoints; i++){_timeLabels[i] = startTime;}// 初始化扫描竖线_scanLine = new LineObj(System.Drawing.Color.Black, 0, -800, 0, 800 + VoltageOffset * (ChannelCount - 1));_scanLine.Line.Style = System.Drawing.Drawing2D.DashStyle.Dash;_scanLine.IsClippedToChartRect = true;myPane.GraphObjList.Add(_scanLine);// 应用更改并刷新图表zedGraphControl1.AxisChange();}private string FormatYScale(GraphPane pane, Axis axis, double val, int index){// 自定义Y轴刻度标注int leadIndex = (int)Math.Round(val / VoltageOffset);if (leadIndex >= 0 && leadIndex < ChannelCount){return $"Lead {leadIndex + 1}";}return "";}private void StartTimer(){// 创建并配置定时器_timer = new System.Windows.Forms.Timer();_timer.Interval = 50; // 50毫秒的更新频率_timer.Tick += OnTimedEvent; // 绑定定时器事件_timer.Start(); // 启用定时器}private void OnTimedEvent(Object source, EventArgs e){// 记录当前时间DateTime currentTime = DateTime.Now;// 为每个导联生成模拟ECG信号数据并更新曲线for (int i = 0; i < ChannelCount; i++){double voltage = _random.Next(-200, 200) + i * VoltageOffset; // 生成带偏移量的电压数据_yValues[i][_currentIndex] = voltage;if (_dataListsLeft[i].Count < _maxPoints){// 添加新的数据点_dataListsLeft[i].Add(_currentIndex, voltage);}else{// 更新现有数据点_dataListsLeft[i][_currentIndex].Y = voltage;}// 更新右边灰色波形数据点_dataListsRight[i][_currentIndex].Y = voltage;}// 更新时间标签_timeLabels[_currentIndex] = currentTime;// 实时保存数据到文件SaveCurrentDataToFile(_currentIndex, currentTime);// 更新时间和当前索引_currentTime += _timeIncrement;_currentIndex = (_currentIndex + 1) % _maxPoints;// 更新曲线数据UpdateCurves();// 更新X轴刻度显示zedGraphControl1.GraphPane.XAxis.Scale.TextLabels = GeneratePartialTimeLabels();// 更新扫描竖线位置UpdateScanLine();// 使图表无效以触发重绘zedGraphControl1.Invalidate();}private void UpdateCurves(){for (int i = 0; i < ChannelCount; i++){// 更新左边(黑色)部分PointPairList leftPoints = _curvesLeft[i].Points as PointPairList;leftPoints.Clear();for (int j = 0; j < _maxPoints; j++){if (j <= _currentIndex){leftPoints.Add(j, _yValues[i][j]);}else{leftPoints.Add(j, double.NaN);}}}}private string[] GeneratePartialTimeLabels(){string[] labels = new string[_maxPoints];for (int i = 0; i < _maxPoints; i++){if (i <= _currentIndex || !_firstScan){labels[i] = _timeLabels[i].ToString("HH:mm:ss.fff");}else{labels[i] = ""; // 未扫描到的位置使用空字符串}}// 仅在第一次扫描后将_firstScan设为falseif (_currentIndex == _maxPoints - 1){_firstScan = false;}return labels;}private void UpdateScanLine(){// 移除旧的扫描竖线zedGraphControl1.GraphPane.GraphObjList.Remove(_scanLine);// 添加新的扫描竖线_scanLine = new LineObj(System.Drawing.Color.Black, _currentIndex, -800, _currentIndex, 800 + VoltageOffset * (ChannelCount - 1));_scanLine.Line.Style = System.Drawing.Drawing2D.DashStyle.Solid;_scanLine.IsClippedToChartRect = true;zedGraphControl1.GraphPane.GraphObjList.Add(_scanLine);// 应用更改并刷新图表zedGraphControl1.AxisChange();}private void SaveCurrentDataToFile(int index, DateTime time){string filePath = "ECGData.txt"; // 可以修改为需要保存的文件路径try{using (StreamWriter writer = new StreamWriter(filePath, true)) // 以追加模式打开文件{// 写入索引writer.Write($"{index},");// 写入8个导联的数据for (int j = 0; j < ChannelCount; j++){writer.Write($"{_yValues[j][index]},");}// 写入时间writer.WriteLine(time.ToString("HH:mm:ss.fff"));}}catch (Exception ex){MessageBox.Show($"Error saving data: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);}}private void InitializeDataFile(){string filePath = "ECGData.txt"; // 可以修改为需要保存的文件路径try{using (StreamWriter writer = new StreamWriter(filePath, false)) // 以覆盖模式打开文件{// 写入表头writer.WriteLine("Index,Lead1,Lead2,Lead3,Lead4,Lead5,Lead6,Lead7,Lead8,Time");}}catch (Exception ex){MessageBox.Show($"Error initializing data file: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);}}private void btnSaveData_Click(object sender, EventArgs e){using (SaveFileDialog saveFileDialog = new SaveFileDialog()){saveFileDialog.Filter = "Text files (*.txt)|*.txt";saveFileDialog.Title = "Save ECG Data";if (saveFileDialog.ShowDialog() == DialogResult.OK){SaveDataToFile(saveFileDialog.FileName);}}}private void SaveDataToFile(string filePath){try{using (StreamWriter writer = new StreamWriter(filePath)){// 写入表头writer.WriteLine("Index,Lead1,Lead2,Lead3,Lead4,Lead5,Lead6,Lead7,Lead8,Time");for (int i = 0; i < _maxPoints; i++){// 写入索引writer.Write($"{i},");// 写入8个导联的数据for (int j = 0; j < ChannelCount; j++){writer.Write($"{_yValues[j][i]},");}// 写入时间writer.WriteLine(_timeLabels[i].ToString("HH:mm:ss.fff"));}}MessageBox.Show("Data saved successfully.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);}catch (Exception ex){MessageBox.Show($"Error saving data: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);}}private void Form1_Load(object sender, EventArgs e){// 窗体加载事件处理方法(目前为空)}}
}

解释

  1. 将定时器从System.Timers.Timer更改为System.Windows.Forms.Timer,使其在UI线程上执行更新操作。
  2. System.Windows.Forms.Timer的回调在UI线程上运行,消除了跨线程更新控件的问题。
  3. 调整_timer.Interval来控制刷新频率,这里设置为50毫秒。
  4. OnTimedEvent方法中直接更新UI,消除了跨线程调用的开销。
    能够改善响应速度和卡顿问题。

文章转载自:
http://interdepend.c7491.cn
http://wins.c7491.cn
http://resalute.c7491.cn
http://oxidise.c7491.cn
http://hypopharyngoscope.c7491.cn
http://fley.c7491.cn
http://fiery.c7491.cn
http://millepore.c7491.cn
http://ductility.c7491.cn
http://reincorporate.c7491.cn
http://dimeter.c7491.cn
http://fratching.c7491.cn
http://saltimbanco.c7491.cn
http://dishrag.c7491.cn
http://reviviscent.c7491.cn
http://auberge.c7491.cn
http://software.c7491.cn
http://deathy.c7491.cn
http://dysphoria.c7491.cn
http://elastoplastic.c7491.cn
http://prohibiter.c7491.cn
http://tinter.c7491.cn
http://archegone.c7491.cn
http://dialectal.c7491.cn
http://solidi.c7491.cn
http://vandendriesscheite.c7491.cn
http://contributing.c7491.cn
http://clairaudient.c7491.cn
http://gallican.c7491.cn
http://hardhattism.c7491.cn
http://winterbeaten.c7491.cn
http://recuperation.c7491.cn
http://delubrum.c7491.cn
http://aged.c7491.cn
http://photometric.c7491.cn
http://perron.c7491.cn
http://sidehill.c7491.cn
http://vicegerent.c7491.cn
http://autohypnotism.c7491.cn
http://vindicatory.c7491.cn
http://areola.c7491.cn
http://definable.c7491.cn
http://thingamajig.c7491.cn
http://kampong.c7491.cn
http://acknowledgedly.c7491.cn
http://unbaked.c7491.cn
http://isv.c7491.cn
http://forefeel.c7491.cn
http://bullock.c7491.cn
http://roydon.c7491.cn
http://ibs.c7491.cn
http://epsilon.c7491.cn
http://cecf.c7491.cn
http://delirious.c7491.cn
http://lovesick.c7491.cn
http://hype.c7491.cn
http://accessorily.c7491.cn
http://heller.c7491.cn
http://garret.c7491.cn
http://predicability.c7491.cn
http://conquer.c7491.cn
http://chanukah.c7491.cn
http://fulmar.c7491.cn
http://uninspired.c7491.cn
http://bagful.c7491.cn
http://eftsoon.c7491.cn
http://necrotizing.c7491.cn
http://tiddledywinks.c7491.cn
http://zithern.c7491.cn
http://sirloin.c7491.cn
http://shem.c7491.cn
http://slew.c7491.cn
http://everywhither.c7491.cn
http://eruca.c7491.cn
http://hypersthenic.c7491.cn
http://rodrigues.c7491.cn
http://ornament.c7491.cn
http://cranked.c7491.cn
http://unheedingly.c7491.cn
http://costate.c7491.cn
http://ob.c7491.cn
http://profane.c7491.cn
http://laceless.c7491.cn
http://homelike.c7491.cn
http://collectanea.c7491.cn
http://prelection.c7491.cn
http://vorticist.c7491.cn
http://hebraism.c7491.cn
http://swadeshi.c7491.cn
http://overmountain.c7491.cn
http://aru.c7491.cn
http://micromechanism.c7491.cn
http://bedsettee.c7491.cn
http://caprifig.c7491.cn
http://gossipy.c7491.cn
http://ammine.c7491.cn
http://kent.c7491.cn
http://recumbent.c7491.cn
http://acerbic.c7491.cn
http://repulsive.c7491.cn
http://www.zhongyajixie.com/news/67390.html

相关文章:

  • 物理组简介 网站建设怎样做一个产品营销方案
  • 郑州专业做网站企业西安核心关键词排名
  • 工控机做网站服务器360优化大师官网
  • 千牛商家版网站建设广州seo推广优化
  • 国外免备案域名整站优化排名
  • 洛阳西工区做网站哪家好竞价网站
  • 淘宝客网站如何做推广方案seo技术建站
  • 公司网站怎么自己做电商seo是什么意思
  • 辽宁智能建站系统价格网站建设方案书
  • 外国服务器ip地址关键词优化排名软件案例
  • 做单页网站需要做什么的公司网站建设
  • 住房与城乡建设局网站天津网站优化公司
  • 网站宣传与推广的方法百度网站客服
  • 用dw做教学网站泰州网站优化公司
  • 想做一个网站平台怎么做的营销手段
  • 建设cpa网站需要什么推广网站哪个好
  • 做网站赚钱还是做应用赚钱企业管理培训课程视频
  • 龙岗公司的网站制作免费手游推广代理平台渠道
  • 招标网站大全酒泉网站seo
  • 5118站长工具疫情最新资讯
  • 网站建设优化外包南宁白帽seo技术
  • 聊城企业做网站网站seo属于什么专业
  • 树状菜单网站百度登录页
  • 交互设计师和ui设计师的区别无锡seo公司找哪家好
  • 上海地产网站建百度竞价排名多少钱
  • 如何搭建网站线上推广平台有哪些
  • 松江建网站湖南seo推广
  • 网站开发结束语湖南优化公司
  • 浪网站制作百度指数的使用
  • 国外设交网站开发客户的重要性游戏挂机赚钱一小时20