System.Drawing.Graphics

  • 绘制一段弧线,它表示由一对坐标、宽度和高度指定的椭圆部分。

  • 绘制一段弧线,它表示由一对坐标、宽度和高度指定的椭圆部分。

  • 绘制一段弧线,它表示RectangleF 结构指定的椭圆的一部分。

  • 绘制一段弧线,它表示Rectangle 结构指定的椭圆的一部分。

  • 释放由Graphics 使用的所有资源。

  • 创建一个对象,该对象包含生成用于与远程对象进行通信的代理所需的全部相关信息。 (继承自MarshalByRefObject。)

  • 绘制由Point 结构的数组定义的闭合基数样条。

  • 绘制由PointF 结构的数组定义的闭合基数样条。

  • 执行颜色数据(对应于由像素组成的矩形)从屏幕到Graphics 的绘图图面的位块传输。

  • 执行颜色数据(对应于由像素组成的矩形)从屏幕到Graphics 的绘图图面的位块传输。

  • 执行颜色数据(对应于由像素组成的矩形)从屏幕到Graphics 的绘图图面的位块传输。

  • 执行颜色数据(对应于由像素组成的矩形)从屏幕到Graphics 的绘图图面的位块传输。

  • 清除整个绘图面并以指定背景色填充。

  • 保存具有此Graphics 的当前状态的图形容器,然后打开并使用具有指定缩放变形的新图形容器。

  • 保存具有此Graphics 的当前状态的图形容器,然后打开并使用具有指定缩放变形的新图形容器。

  • 保存具有此Graphics 的当前状态的图形容器,然后打开并使用新的图形容器。

  • 向当前Metafile 添加注释。

  • 绘制由 4 个Point 结构定义的贝塞尔样条。

  • 绘制由 4 个PointF 结构定义的贝塞尔样条。

  • 绘制由四个表示点的有序坐标对定义的贝塞尔样条。

  • 用Point 结构数组绘制一系列贝塞尔样条。

  • 用PointF 结构数组绘制一系列贝塞尔样条。

  • 使用指定的张力绘制由Point 结构数组定义的闭合基数样条。

  • 使用指定的张力绘制由PointF 结构数组定义的闭合基数样条。

  • 绘制经过一组指定的Point 结构的基数样条。

  • 绘制经过一组指定的PointF 结构的基数样条。

  • 使用指定的张力绘制经过一组指定的Point 结构的基数样条。

  • 使用指定的张力绘制经过一组指定的PointF 结构的基数样条。

  • 绘制边界RectangleF 定义的椭圆。

  • 绘制一个由边框定义的椭圆,该边框由矩形的左上角坐标、高度和宽度指定。

  • 绘制一个由边框(该边框由一对坐标、高度和宽度指定)定义的椭圆。

  • 绘制经过一组指定的PointF 结构的基数样条。从相对于数组开始位置的偏移量开始绘制。

  • 使用指定的张力绘制经过一组指定的Point 结构的基数样条。

  • 使用指定的张力绘制经过一组指定的PointF 结构的基数样条。从相对于数组开始位置的偏移量开始绘制。

  • 绘制边界Rectangle 结构指定的椭圆。

  • 在Rectangle 结构指定的区域内绘制指定的Icon 表示的图像。

  • 在指定坐标处绘制由指定的Icon 表示的图像。

  • 绘制指定的Icon 表示的图像,而不缩放该图像。

  • 在指定的位置使用原始物理大小绘制指定的Image。

  • 在指定位置并且按指定形状和大小绘制指定的Image。

  • 在指定的位置使用原始物理大小绘制指定的Image。

  • 在指定位置并且按指定大小绘制指定的Image。

  • 在由坐标对指定的位置,使用图像的原始物理大小绘制指定的图像。

  • 在指定的位置使用原始物理大小绘制指定的Image。

  • 在指定位置并且按指定形状和大小绘制指定的Image。

  • 在指定位置并且按指定大小绘制指定的Image。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定的位置绘制图像的一部分。

  • 在指定位置并且按指定大小绘制指定的Image。

  • 在指定的位置绘制图像的一部分。

  • 在指定位置并且按指定大小绘制指定的Image。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 绘制一条连接由坐标对指定的两个点的线条。

  • 绘制一条连接由坐标对指定的两个点的线条。

  • 绘制一系列连接一组Point 结构的线段。

  • 绘制一系列连接一组PointF 结构的线段。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定的位置使用图像的原始物理大小绘制指定的图像。

  • 在不进行缩放的情况下绘制指定的图像,并在需要时剪辑该图像以适合指定的矩形。

  • 绘制一条连接两个Point 结构的线。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定的位置使用图像的原始物理大小绘制指定的图像。

  • 绘制一条连接两个PointF 结构的线。

  • 在指定位置并且按指定大小绘制指定的Image 的指定部分。

  • 在指定的位置使用图像的原始物理大小绘制指定的图像。

  • 在由坐标对指定的位置,使用图像的原始物理大小绘制指定的图像。

  • 绘制由一个RectangleF 结构和两条射线所指定的椭圆定义的扇形。

  • 绘制一个扇形,该形状由一个坐标对、宽度、高度以及两条射线所指定的椭圆定义。

  • 绘制一个扇形,该形状由一个坐标对、宽度、高度以及两条射线所指定的椭圆定义。

  • 绘制由一组Point 结构定义的多边形。

  • 绘制由一组PointF 结构定义的多边形。

  • 绘制由Rectangle 结构指定的矩形。

  • 绘制GraphicsPath。

  • 绘制由一个Rectangle 结构和两条射线所指定的椭圆定义的扇形。

  • 使用指定StringFormat 的格式化属性,用指定的Brush 和Font 对象在指定的矩形绘制指定的文本字符串。

  • 在指定位置并且用指定的Brush 和Font 对象绘制指定的文本字符串。

  • 绘制由坐标对、宽度和高度指定的矩形。

  • 绘制由坐标对、宽度和高度指定的矩形。

  • 绘制一系列由Rectangle 结构指定的矩形。

  • 绘制一系列由RectangleF 结构指定的矩形。

  • 在指定位置并且用指定的Brush 和Font 对象绘制指定的文本字符串。

  • 在指定矩形并且用指定的Brush 和Font 对象绘制指定的文本字符串。

  • 使用指定StringFormat 的格式化属性,用指定的Brush 和Font 对象在指定的位置绘制指定的文本字符串。

  • 使用指定StringFormat 的格式化属性,用指定的Brush 和Font 对象在指定的位置绘制指定的文本字符串。

  • 关闭当前图形容器,并将此Graphics 的状态还原到通过调用BeginContainer 方法保存的状态。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的点处显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的平行四边形中显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的点处显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的矩形中显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的矩形中显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的点处显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的平行四边形中显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的点处显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的平行四边形中显示。

  • 将指定Metafile 中的记录逐个发送到回调方法,以在指定的平行四边形中用指定的图像属性显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的平行四边形中显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的平行四边形中显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的点处显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的点处显示。

  • 将指定Metafile 中的记录逐个发送到回调方法,以在指定的平行四边形中用指定的图像属性显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的平行四边形中显示。

  • 将指定Metafile 中的记录逐个发送到回调方法,以在指定的点处用指定的图像属性显示。

  • 将指定Metafile 中的记录逐个发送到回调方法,以在指定的矩形中用指定的图像属性显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的平行四边形中显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的点处显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的矩形中显示。

  • 将指定Metafile 中的记录逐个发送到回调方法以在指定的矩形中显示。

  • 将指定Metafile 中的记录逐个发送到回调方法,以在指定的点处用指定的图像属性显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的点处显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的平行四边形中显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的矩形中显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的矩形中显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法,以在指定的点处用指定的图像属性显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法,以在指定的平行四边形中用指定的图像属性显示。

  • 使用指定的填充模式和张力填充Point 结构数组定义的闭合基数样条曲线的内部。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法,以在指定的点处用指定的图像属性显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的矩形中显示。

  • 将指定Metafile 中的记录逐个发送到回调方法,以在指定的矩形中用指定的图像属性显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法以在指定的矩形中显示。

  • 更新此Graphics 的剪辑区域,以排除Region 所指定的区域。

  • 填充由Point 结构数组定义的闭合基数样条曲线的内部。

  • 填充椭圆所定义的扇形区的内部,该椭圆由RectangleF 结构和两条射线指定。

  • 填充由一对坐标、一个宽度、一个高度以及两条射线指定的椭圆所定义的扇形区的内部。

  • 填充由一对坐标、一个宽度、一个高度以及两条射线指定的椭圆所定义的扇形区的内部。

  • 填充由PointF 结构数组定义的闭合基数样条曲线的内部。

  • 使用指定的填充模式填充Point 结构数组定义的闭合基数样条曲线的内部。

  • 使用指定的填充模式填充PointF 结构数组定义的闭合基数样条曲线的内部。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法,以在指定的平行四边形中用指定的图像属性显示。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法,以在指定的矩形中用指定的图像属性显示。

  • 填充RectangleF 结构指定的矩形的内部。

  • 填充由一对坐标、一个宽度和一个高度指定的矩形的内部。

  • 填充由一对坐标、一个宽度和一个高度指定的矩形的内部。

  • 将Metafile 中选定矩形内的记录逐个发送到回调方法,以在指定的矩形中用指定的图像属性显示。

  • 确定指定的Object 是否等于当前的Object。(继承自Object。)

  • 更新此Graphics 的剪辑区域,以排除Rectangle 结构所指定的区域。

  • 填充GraphicsPath 的内部。

  • 填充Point 结构指定的点数组所定义的多边形的内部。

  • 用此方法强制执行所有挂起的图形操作,按照指定,等待或者不等待,在操作完成之前返回。

  • 从设备上下文的指定句柄创建新的Graphics。

  • 填充PointF 结构指定的点数组所定义的多边形的内部。

  • 使用指定的填充模式填充Point 结构指定的点数组所定义的多边形的内部。

  • 使用指定的填充模式填充PointF 结构指定的点数组所定义的多边形的内部。

  • 使用指定的填充模式和张力填充PointF 结构数组定义的闭合基数样条曲线的内部。

  • 填充Rectangle 结构指定的边框所定义的椭圆的内部。

  • 填充RectangleF 结构指定的边框所定义的椭圆的内部。

  • 填充边框所定义的椭圆的内部,该边框由一对坐标、一个宽度和一个高度指定。

  • 填充Rectangle 结构指定的矩形的内部。

  • 填充边框所定义的椭圆的内部,该边框由一对坐标、一个宽度和一个高度指定。

  • 强制执行所有挂起的图形操作并立即返回而不等待操作完成。

  • 从设备上下文的指定句柄和设备的句柄创建新的Graphics。

  • 基础结构。返回指定设备上下文的Graphics。

  • 从窗口的指定句柄创建新的Graphics。

  • 基础结构。创建指定 Windows 句柄的新Graphics。

  • 从指定的Image 创建新的Graphics。

  • 基础结构。获取累积的图形上下文。

  • 获取当前 Windows 的半色调调色板的句柄。

  • 用作特定类型的哈希函数。 (继承自Object。)

  • 填充由Rectangle 结构指定的一系列矩形的内部。

  • 填充由RectangleF 结构指定的一系列矩形的内部。

  • 填充Region 的内部。

  • 允许Object 在“垃圾回收”回收Object 之前尝试释放资源并执行其他清理操作。(继承自Object。)

  • 获取与指定的Color 结构最接近的颜色。

  • 获取当前实例的Type。(继承自Object。)

  • 获取控制此实例的生存期策略的生存期服务对象。 (继承自MarshalByRefObject。)

  • 将此Graphics 的剪辑区域更新为当前剪辑区域与指定Rectangle 结构的交集。

  • 获取与此Graphics 关联的设备上下文的句柄。

  • 检索控制此实例的生存期策略的当前生存期服务对象。 (继承自MarshalByRefObject。)

  • 将此Graphics 的剪辑区域更新为当前剪辑区域与指定RectangleF 结构的交集。

  • 将此Graphics 对象的剪辑区域更新为当前剪辑区域与指定Region 的交集。

  • 指示指定的Point 结构是否包含在此Graphics 的可见剪辑区域内。

  • 指示指定的PointF 结构是否包含在此Graphics 的可见剪辑区域内。

  • 指示Rectangle 结构指定的矩形是否包含在此Graphics 的可见剪辑区域内。

  • 指示RectangleF 结构指定的矩形是否包含在此Graphics 的可见剪辑区域内。

  • 指示由一对坐标指定的点是否包含在此Graphics 的可见剪辑区域内。

  • 指示由一对坐标指定的点是否包含在此Graphics 的可见剪辑区域内。

  • 指示由一对坐标、一个宽度和一个高度指定的矩形是否包含在此Graphics 的可见剪辑区域内。

  • 指示由一对坐标、一个宽度和一个高度指定的矩形是否包含在此Graphics 的可见剪辑区域内。

  • 获取Region 对象的数组,其中每个对象将字符位置的范围限定在指定字符串内。

  • 测量用指定的Font 绘制的指定字符串。

  • 当在指定的布局区域内以指定的Font 绘制时,测量指定的字符串。

  • 测量用指定的Font 绘制的指定字符串。

  • 测量用指定的Font 绘制并用指定的StringFormat 格式化的指定字符串。

  • 测量用指定的Font 绘制并用指定的StringFormat 格式化的指定字符串。

  • 测量用指定的Font 绘制并用指定的StringFormat 格式化的指定字符串。

  • 测量用指定的Font 绘制并用指定的StringFormat 格式化的指定字符串。

  • 创建当前Object 的浅表副本。(继承自Object。)

  • 基础结构。释放设备上下文的句柄。

  • 将此Graphics 的剪辑区域重置为无限区域。

  • 将此Graphics 的世界变换矩阵重置为单位矩阵。

  • 将此Graphics 的状态还原到GraphicsState 表示的状态。

  • 创建当前MarshalByRefObject 对象的浅表副本。(继承自MarshalByRefObject。)

  • 将指定旋转应用于此Graphics 的变换矩阵。

  • 将此Graphics 的世界变换乘以指定的Matrix。

  • 以指定顺序将此Graphics 的世界变换乘以指定的Matrix。

  • 释放通过以前对此Graphics 的GetHdc 方法的调用获得的设备上下文句柄。

  • 释放通过以前对此Graphics 的GetHdc 方法的调用获得的设备上下文句柄。

  • 保存此Graphics 的当前状态,并用GraphicsState 标识保存的状态。

  • 将指定的缩放操作应用于此Graphics 的变换矩阵,方法是将该对象的变换矩阵左乘该缩放矩阵。

  • 以指定顺序将指定的缩放操作应用到此Graphics 的变换矩阵。

  • 将此Graphics 的剪辑区域设置为指定Graphics 的Clip 属性。

  • 以指定顺序将指定旋转应用到此Graphics 的变换矩阵。

  • 将此Graphics 的剪辑区域设置为指定的GraphicsPath。

  • 将此Graphics 的剪辑区域设置为Rectangle 结构指定的矩形。

  • 将此Graphics 的剪辑区域设置为RectangleF 结构指定的矩形。

  • 将此Graphics 的剪辑区域设置为当前剪辑区域和指定的Graphics 的Clip 属性指定的组合操作的结果。

  • 使用此Graphics 的当前世界变换和页变换,将点数组从一个坐标空间转换到另一个坐标空间。

  • 将此Graphics 的剪辑区域沿水平方向和垂直方向平移指定的量。

  • 将此Graphics 的剪辑区域沿水平方向和垂直方向平移指定的量。

  • 通过使此Graphics 的变换矩阵左乘指定的平移来更改坐标系统的原点。

  • 将此Graphics 的剪辑区域设置为当前剪辑区域与指定GraphicsPath 的组合结果。

  • 将此Graphics 的剪辑区域设置为当前剪辑区域与Rectangle 结构所指定矩形的组合结果。

  • 将此Graphics 的剪辑区域设置为当前剪辑区域与RectangleF 结构所指定矩形的组合结果。

  • 通过以指定顺序将指定平移应用于此Graphics 的变换矩阵来更改坐标系统的原点。

  • 将此Graphics 的剪辑区域设置为当前剪辑区域与指定Region 的组合结果。

  • 返回表示当前Object 的String。(继承自Object。)

  • 使用此Graphics 的当前世界变换和页变换,将点数组从一个坐标空间转换到另一个坐标空间。

Graphics的属性

  • 获取或设置Region,该对象限定此Graphics 的绘图区域。

  • 获取此Graphics 的水平分辨率。

  • 获取一个RectangleF 结构,该结构限定此Graphics 的剪辑区域。

  • 获取一个值,该值指定如何将合成图像绘制到此Graphics。

  • 获取或设置绘制到此Graphics 的合成图像的呈现质量。

  • 获取此Graphics 的垂直分辨率。

  • 获取或设置与此Graphics 关联的插补模式。

  • 获取一个值,该值指示此Graphics 的剪辑区域是否为空。

  • 获取一个值,该值指示此Graphics 的可见剪辑区域是否为空。

  • 获取或设置此Graphics 的世界单位和页单位之间的比例。

  • 获取或设置用于此Graphics 中的页坐标的度量单位。

  • 获取或设置一个值,该值指定在呈现此Graphics 的过程中像素如何偏移。

  • 为抵色处理和阴影画笔获取或设置此Graphics 的呈现原点。

  • 获取或设置此Graphics 的呈现质量。

  • 获取或设置呈现文本的灰度校正值。

  • 获取或设置与此Graphics 关联的文本的呈现模式。

  • 获取或设置此Graphics 的几何世界变换的副本。

  • 获取此Graphics 的可见剪辑区域的边框。

# 气垫导轨实验系统 - 文件组织与实现 在 WinForms 项目中,核心实现代码和界面设计代码通常分别存放在不同的文件中,遵循 C# 的 partial 类设计模式。以下是完整的文件组织方案: ## 文件结构 ``` PhysicsExperimentMonitor/ ├── MainForm.cs // 核心逻辑代码 ├── MainForm.Designer.cs // 界面设计代码 ├── Program.cs // 应用程序入口 └── ExperimentData.cs // 实验数据模型(可选) ``` ## 1. MainForm.cs - 核心逻辑实现 ```csharp using System; using System.Collections.Generic; using System.Drawing; using System.IO.Ports; using System.Text.RegularExpressions; using System.Windows.Forms; using System.Windows.Forms.DataVisualization.Charting; namespace PhysicsExperimentMonitor { public partial class MainForm : Form { // 实验数据结构 public class ExperimentData { // 属性定义(与之前相同) // ... } // 成员变量 private SerialPort serialPort; private List<ExperimentData> experimentHistory = new List<ExperimentData>(); private int currentExperimentId = 1; private ExperimentData currentExperiment; // 当前实验参数 private double currentLightBlockWidth; private double currentGateDistance; private double currentSliderMass; private double currentWeightMass; // 正则表达式 private Regex timeRegex = new Regex(@"光电门(\d)挡光时间[::]\s*(\d+\.?\d*)\s*s"); private Regex velocityRegex = new Regex(@"通过光电门(\d)速度[::]\s*(\d+\.?\d*)\s*m/s"); private Regex accelRegex = new Regex(@"加速度[::]\s*(\d+\.?\d*)\s*m/s²"); private Regex dataStartRegex = new Regex(@"=+实验数据=+"); public MainForm() { InitializeComponent(); InitializeSerialPort(); InitializeChart(); InitializeDataGridView(); // 填充可用串口 cmbPorts.Items.AddRange(SerialPort.GetPortNames()); if (cmbPorts.Items.Count > 0) cmbPorts.SelectedIndex = 0; // 设置默认波特率 cmbBaudRate.SelectedIndex = 3; // 115200 // 设置默认参数值 txtLightBlockWidth.Text = "0.01"; txtGateDistance.Text = "0.3"; txtSliderMass.Text = "0.2"; txtWeightMass.Text = "0.05"; lblStatus.Text = "就绪"; btnEndExperiment.Enabled = false; } private void InitializeSerialPort() { serialPort = new SerialPort(); serialPort.DataReceived += SerialPort_DataReceived; } private void InitializeChart() { // 图表初始化代码(与之前相同) // ... } private void InitializeDataGridView() { // 数据表格初始化代码(与之前相同) // ... } // 启动新实验 private void btnStartExperiment_Click(object sender, EventArgs e) { // 启动实验逻辑(与之前相同) // ... } // 结束当前实验 private void btnEndExperiment_Click(object sender, EventArgs e) { // 结束实验逻辑(与之前相同) // ... } // 数据接收处理 private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { // 串口数据处理(与之前相同) // ... } // 处理串口数据 private void ProcessSerialData(string data) { // 数据解析逻辑(与之前相同) // ... } // 完成当前实验数据的收集 private void CompleteExperiment() { // 完成实验逻辑(与之前相同) // ... } // 更新数据显示 private void UpdateDataDisplay(ExperimentData data) { // 更新表格显示(与之前相同) // ... } // 更新图表 private void UpdateChart() { // 更新图表(与之前相同) // ... } // 连接串口 private void btnConnect_Click(object sender, EventArgs e) { // 串口连接逻辑(与之前相同) // ... } // 清空数据 private void btnClearData_Click(object sender, EventArgs e) { // 清空数据逻辑(与之前相同) // ... } // 参数输入验证 private void ValidateNumericInput(object sender, EventArgs e) { TextBox textBox = sender as TextBox; if (textBox != null) { if (!double.TryParse(textBox.Text, out double value) || value <= 0) { textBox.BackColor = Color.LightPink; btnStartExperiment.Enabled = false; } else { textBox.BackColor = SystemColors.Window; btnStartExperiment.Enabled = double.TryParse(txtLightBlockWidth.Text, out _) && double.TryParse(txtGateDistance.Text, out _) && double.TryParse(txtSliderMass.Text, out _) && double.TryParse(txtWeightMass.Text, out _); } } } // 关闭窗体时断开串口 private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { if (serialPort != null && serialPort.IsOpen) serialPort.Close(); } } } ``` ## 2. MainForm.Designer.cs - 界面设计代码 ```csharp namespace PhysicsExperimentMonitor { partial class MainForm { private System.ComponentModel.IContainer components = null; // 控件声明 private ComboBox cmbPorts; private ComboBox cmbBaudRate; private Button btnConnect; private DataGridView dgvData; private Button btnExport; private RichTextBox txtLog; private Chart chartAcceleration; private Label label1; private Label label2; private TextBox txtLightBlockWidth; private TextBox txtGateDistance; private TextBox txtSliderMass; private TextBox txtWeightMass; private Label label3; private Label label4; private Label label5; private Label label6; private Button btnStartExperiment; private Button btnEndExperiment; private Label lblStatus; private Button btnClearData; protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } private void InitializeComponent() { System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle(); System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle2 = new System.Windows.Forms.DataGridViewCellStyle(); System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea(); System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend(); System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series(); System.Windows.Forms.DataVisualization.Charting.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series(); System.Windows.Forms.DataVisualization.Charting.Series series3 = new System.Windows.Forms.DataVisualization.Charting.Series(); System.Windows.Forms.DataVisualization.Charting.Series series4 = new System.Windows.Forms.DataVisualization.Charting.Series(); this.cmbPorts = new System.Windows.Forms.ComboBox(); this.cmbBaudRate = new System.Windows.Forms.ComboBox(); this.btnConnect = new System.Windows.Forms.Button(); this.dgvData = new System.Windows.Forms.DataGridView(); this.btnExport = new System.Windows.Forms.Button(); this.txtLog = new System.Windows.Forms.RichTextBox(); this.chartAcceleration = new System.Windows.Forms.DataVisualization.Charting.Chart(); this.label1 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.txtLightBlockWidth = new System.Windows.Forms.TextBox(); this.txtGateDistance = new System.Windows.Forms.TextBox(); this.txtSliderMass = new System.Windows.Forms.TextBox(); this.txtWeightMass = new System.Windows.Forms.TextBox(); this.label3 = new System.Windows.Forms.Label(); this.label4 = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label(); this.label6 = new System.Windows.Forms.Label(); this.btnStartExperiment = new System.Windows.Forms.Button(); this.btnEndExperiment = new System.Windows.Forms.Button(); this.lblStatus = new System.Windows.Forms.Label(); this.btnClearData = new System.Windows.Forms.Button(); ((System.ComponentModel.ISupportInitialize)(this.dgvData)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.chartAcceleration)).BeginInit(); this.SuspendLayout(); // cmbPorts this.cmbPorts.FormattingEnabled = true; this.cmbPorts.Location = new System.Drawing.Point(20, 20); this.cmbPorts.Name = "cmbPorts"; this.cmbPorts.Size = new System.Drawing.Size(120, 28); this.cmbPorts.TabIndex = 0; // cmbBaudRate this.cmbBaudRate.FormattingEnabled = true; this.cmbBaudRate.Items.AddRange(new object[] { "9600", "19200", "38400", "57600", "115200"}); this.cmbBaudRate.Location = new System.Drawing.Point(150, 20); this.cmbBaudRate.Name = "cmbBaudRate"; this.cmbBaudRate.Size = new System.Drawing.Size(120, 28); this.cmbBaudRate.TabIndex = 1; // btnConnect this.btnConnect.Location = new System.Drawing.Point(280, 20); this.btnConnect.Name = "btnConnect"; this.btnConnect.Size = new System.Drawing.Size(120, 30); this.btnConnect.TabIndex = 2; this.btnConnect.Text = "连接串口"; this.btnConnect.UseVisualStyleBackColor = true; this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click); // dgvData this.dgvData.AllowUserToAddRows = false; this.dgvData.AllowUserToDeleteRows = false; this.dgvData.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.dgvData.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill; this.dgvData.BackgroundColor = System.Drawing.SystemColors.ControlLightLight; this.dgvData.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; this.dgvData.Location = new System.Drawing.Point(20, 220); this.dgvData.Name = "dgvData"; this.dgvData.ReadOnly = true; this.dgvData.RowHeadersWidth = 51; this.dgvData.RowTemplate.Height = 24; this.dgvData.Size = new System.Drawing.Size(1200, 250); this.dgvData.TabIndex = 3; // btnExport this.btnExport.Location = new System.Drawing.Point(410, 20); this.btnExport.Name = "btnExport"; this.btnExport.Size = new System.Drawing.Size(120, 30); this.btnExport.TabIndex = 4; this.btnExport.Text = "导出数据"; this.btnExport.UseVisualStyleBackColor = true; this.btnExport.Click += new System.EventHandler(this.btnExport_Click); // txtLog this.txtLog.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.txtLog.BackColor = System.Drawing.Color.Black; this.txtLog.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.txtLog.ForeColor = System.Drawing.Color.White; this.txtLog.Location = new System.Drawing.Point(20, 480); this.txtLog.Name = "txtLog"; this.txtLog.Size = new System.Drawing.Size(1200, 150); this.txtLog.TabIndex = 5; this.txtLog.Text = ""; // chartAcceleration this.chartAcceleration.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); chartArea1.Name = "ChartArea1"; this.chartAcceleration.ChartAreas.Add(chartArea1); legend1.Name = "Legend1"; this.chartAcceleration.Legends.Add(legend1); this.chartAcceleration.Location = new System.Drawing.Point(430, 60); this.chartAcceleration.Name = "chartAcceleration"; series1.ChartArea = "ChartArea1"; series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; series1.Legend = "Legend1"; series1.Name = "实测加速度"; series2.ChartArea = "ChartArea1"; series2.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; series2.Legend = "Legend1"; series2.Name = "理论加速度"; series3.ChartArea = "ChartArea1"; series3.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; series3.Legend = "Legend1"; series3.Name = "单片机加速度"; series4.ChartArea = "ChartArea1"; series4.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; series4.Legend = "Legend1"; series4.Name = "误差(%)"; this.chartAcceleration.Series.Add(series1); this.chartAcceleration.Series.Add(series2); this.chartAcceleration.Series.Add(series3); this.chartAcceleration.Series.Add(series4); this.chartAcceleration.Size = new System.Drawing.Size(790, 150); this.chartAcceleration.TabIndex = 6; this.chartAcceleration.Text = "chart1"; // label1 this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(20, 70); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(117, 20); this.label1.TabIndex = 7; this.label1.Text = "挡光片宽度(m):"; // label2 this.label2.AutoSize = true; this.label2.Location = new System.Drawing.Point(20, 100); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(117, 20); this.label2.TabIndex = 8; this.label2.Text = "光电门间距(m):"; // txtLightBlockWidth this.txtLightBlockWidth.Location = new System.Drawing.Point(150, 67); this.txtLightBlockWidth.Name = "txtLightBlockWidth"; this.txtLightBlockWidth.Size = new System.Drawing.Size(100, 27); this.txtLightBlockWidth.TabIndex = 9; this.txtLightBlockWidth.Text = "0.01"; this.txtLightBlockWidth.TextChanged += new System.EventHandler(this.ValidateNumericInput); // txtGateDistance this.txtGateDistance.Location = new System.Drawing.Point(150, 97); this.txtGateDistance.Name = "txtGateDistance"; this.txtGateDistance.Size = new System.Drawing.Size(100, 27); this.txtGateDistance.TabIndex = 10; this.txtGateDistance.Text = "0.3"; this.txtGateDistance.TextChanged += new System.EventHandler(this.ValidateNumericInput); // txtSliderMass this.txtSliderMass.Location = new System.Drawing.Point(150, 127); this.txtSliderMass.Name = "txtSliderMass"; this.txtSliderMass.Size = new System.Drawing.Size(100, 27); this.txtSliderMass.TabIndex = 12; this.txtSliderMass.Text = "0.2"; this.txtSliderMass.TextChanged += new System.EventHandler(this.ValidateNumericInput); // txtWeightMass this.txtWeightMass.Location = new System.Drawing.Point(150, 157); this.txtWeightMass.Name = "txtWeightMass"; this.txtWeightMass.Size = new System.Drawing.Size(100, 27); this.txtWeightMass.TabIndex = 13; this.txtWeightMass.Text = "0.05"; this.txtWeightMass.TextChanged += new System.EventHandler(this.ValidateNumericInput); // label3 this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(20, 130); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(117, 20); this.label3.TabIndex = 14; this.label3.Text = "滑块质量(kg):"; // label4 this.label4.AutoSize = true; this.label4.Location = new System.Drawing.Point(20, 160); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(117, 20); this.label4.TabIndex = 15; this.label4.Text = "砝码质量(kg):"; // label5 this.label5.AutoSize = true; this.label5.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.label5.Location = new System.Drawing.Point(280, 70); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(130, 20); this.label5.TabIndex = 16; this.label5.Text = "实验参数设置"; // label6 this.label6.AutoSize = true; this.label6.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.label6.Location = new System.Drawing.Point(20, 190); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(130, 20); this.label6.TabIndex = 17; this.label6.Text = "实验数据表格"; // btnStartExperiment this.btnStartExperiment.BackColor = System.Drawing.Color.LightGreen; this.btnStartExperiment.Location = new System.Drawing.Point(280, 100); this.btnStartExperiment.Name = "btnStartExperiment"; this.btnStartExperiment.Size = new System.Drawing.Size(120, 40); this.btnStartExperiment.TabIndex = 18; this.btnStartExperiment.Text = "开始实验"; this.btnStartExperiment.UseVisualStyleBackColor = false; this.btnStartExperiment.Click += new System.EventHandler(this.btnStartExperiment_Click); // btnEndExperiment this.btnEndExperiment.BackColor = System.Drawing.Color.LightCoral; this.btnEndExperiment.Location = new System.Drawing.Point(280, 150); this.btnEndExperiment.Name = "btnEndExperiment"; this.btnEndExperiment.Size = new System.Drawing.Size(120, 40); this.btnEndExperiment.TabIndex = 19; this.btnEndExperiment.Text = "结束实验"; this.btnEndExperiment.UseVisualStyleBackColor = false; this.btnEndExperiment.Click += new System.EventHandler(this.btnEndExperiment_Click); // lblStatus this.lblStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.lblStatus.BackColor = System.Drawing.SystemColors.Info; this.lblStatus.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.lblStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lblStatus.Location = new System.Drawing.Point(430, 20); this.lblStatus.Name = "lblStatus"; this.lblStatus.Size = new System.Drawing.Size(790, 30); this.lblStatus.TabIndex = 20; this.lblStatus.Text = "就绪"; this.lblStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // btnClearData this.btnClearData.BackColor = System.Drawing.Color.LightSalmon; this.btnClearData.Location = new System.Drawing.Point(410, 150); this.btnClearData.Name = "btnClearData"; this.btnClearData.Size = new System.Drawing.Size(120, 40); this.btnClearData.TabIndex = 21; this.btnClearData.Text = "清空数据"; this.btnClearData.UseVisualStyleBackColor = false; this.btnClearData.Click += new System.EventHandler(this.btnClearData_Click); // MainForm this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1240, 650); this.Controls.Add(this.btnClearData); this.Controls.Add(this.lblStatus); this.Controls.Add(this.btnEndExperiment); this.Controls.Add(this.btnStartExperiment); this.Controls.Add(this.label6); this.Controls.Add(this.label5); this.Controls.Add(this.label4); this.Controls.Add(this.label3); this.Controls.Add(this.txtWeightMass); this.Controls.Add(this.txtSliderMass); this.Controls.Add(this.txtGateDistance); this.Controls.Add(this.txtLightBlockWidth); this.Controls.Add(this.label2); this.Controls.Add(this.label1); this.Controls.Add(this.chartAcceleration); this.Controls.Add(this.txtLog); this.Controls.Add(this.btnExport); this.Controls.Add(this.dgvData); this.Controls.Add(this.btnConnect); this.Controls.Add(this.cmbBaudRate); this.Controls.Add(this.cmbPorts); this.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.Margin = new System.Windows.Forms.Padding(4); this.Name = "MainForm"; this.Text = "气垫导轨实验系统"; this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing); ((System.ComponentModel.ISupportInitialize)(this.dgvData)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.chartAcceleration)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } } } ``` ## 3. Program.cs - 应用程序入口 ```csharp using System; using System.Windows.Forms; namespace PhysicsExperimentMonitor { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new MainForm()); } } } ``` ## 4. ExperimentData.cs - 数据模型(可选) ```csharp using System; namespace PhysicsExperimentMonitor { public class ExperimentData { public int ExperimentID { get; set; } public DateTime Timestamp { get; set; } public double LightBlockWidth { get; set; } public double GateDistance { get; set; } public double TimeGate1 { get; set; } public double TimeGate2 { get; set; } public double SliderMass { get; set; } public double WeightMass { get; set; } public double Velocity1 => LightBlockWidth / TimeGate1; public double Velocity2 => LightBlockWidth / TimeGate2; public double TotalMass => SliderMass + WeightMass; public double PullForce => WeightMass * 9.8; public double Acceleration => (Velocity2 * Velocity2 - Velocity1 * Velocity1) / (2 * GateDistance); public double ExpectedAcceleration => PullForce / TotalMass; public double MCU_Velocity1 { get; set; } public double MCU_Velocity2 { get; set; } public double MCU_Acceleration { get; set; } public double ErrorPercentage => Math.Abs(Acceleration - ExpectedAcceleration) / ExpectedAcceleration * 100; } } ``` ## 系统实现要点 1. **Partial 类设计**: - `MainForm.cs` 包含业务逻辑和事件处理 - `MainForm.Designer.cs` 包含界面布局和控件初始化 - 两部分通过 `partial class MainForm` 组合 2. **数据流处理**: - 串口数据接收 → 正则表达式解析 → 数据存储 → UI 更新 3. **参数动态设置**: - 每次实验前可修改挡光片宽度、光电门间距等参数 - 参数验证确保输入有效性 4. **多行数据解析**: - 使用正则表达式处理不同格式的数据行 - 自动识别数据开始标记和结束标记 5. **错误处理**: - 参数验证防止无效输入 - 异常捕获确保程序稳定性 - 状态指示器显示当前系统状态
最新发布
11-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值