一、核心思路
工控指示灯核心是圆形显示 + 状态对应颜色 + 可选闪烁效果,通过自定义UserControl实现可复用性,支持自定义状态、颜色、大小及闪烁开关,满足工控场景的多样化需求。
二、完整实现代码
1. 自定义工控指示灯控件(IndustrialLed.cs)
using System;using System.Drawing;using System.Windows.Forms;using System.ComponentModel;namespace IndustrialControls{ /// <summary> /// 自定义工控指示灯控件 /// 支持多状态切换、颜色自定义、闪烁效果 /// </summary> public partial class IndustrialLed : UserControl { #region 私有字段 // 指示灯状态(默认待机) private LedStatus _currentStatus = LedStatus.Standby; // 各状态对应的颜色(可自定义) private Color _runningColor = Color.LimeGreen; // 运行状态-绿色 private Color _faultColor = Color.Red; // 故障状态-红色 private Color _standbyColor = Color.Gray; // 待机状态-灰色 private Color _warningColor = Color.Orange; // 警告状态-橙色 // 闪烁相关 private Timer _flashTimer; private bool _isFlashVisible = true; private bool _enableFlash = false; #endregion #region 公共枚举(指示灯状态) /// <summary> /// 工控指示灯状态枚举 /// 可根据业务扩展(如添加:停止、通讯异常等) /// </summary> public enum LedStatus { /// <summary>待机/未运行</summary> Standby, /// <summary>正常运行</summary> Running, /// <summary>故障/异常</summary> Fault, /// <summary>警告/待处理</summary> Warning } #endregion #region 公共属性(支持设计时编辑) /// <summary> /// 当前指示灯状态 /// </summary> [Description("当前工控指示灯状态"), Category("工控指示灯设置")] public LedStatus CurrentStatus { get => _currentStatus; set { _currentStatus = value; // 状态变更时重绘控件 Invalidate(); // 状态变更时控制闪烁定时器 UpdateFlashTimer(); } } /// <summary> /// 运行状态颜色 /// </summary> [Description("运行状态对应的指示灯颜色"), Category("工控指示灯设置")] public Color RunningColor { get => _runningColor; set { _runningColor = value; Invalidate(); } } /// <summary> /// 故障状态颜色 /// </summary> [Description("故障状态对应的指示灯颜色"), Category("工控指示灯设置")] public Color FaultColor { get => _faultColor; set { _faultColor = value; Invalidate(); } } /// <summary> /// 待机状态颜色 /// </summary> [Description("待机状态对应的指示灯颜色"), Category("工控指示灯设置")] public Color StandbyColor { get => _standbyColor; set { _standbyColor = value; Invalidate(); } } /// <summary> /// 警告状态颜色 /// </summary> [Description("警告状态对应的指示灯颜色"), Category("工控指示灯设置")] public Color WarningColor { get => _warningColor; set { _warningColor = value; Invalidate(); } } /// <summary> /// 是否启用闪烁效果(仅故障/警告状态生效) /// </summary> [Description("是否启用闪烁效果(故障/警告状态生效)"), Category("工控指示灯设置")] public bool EnableFlash { get => _enableFlash; set { _enableFlash = value; UpdateFlashTimer(); } } /// <summary> /// 闪烁间隔(毫秒),默认500ms /// </summary> [Description("指示灯闪烁间隔(毫秒)"), Category("工控指示灯设置")] public int FlashInterval { get; set; } = 500; #endregion #region 构造函数 public IndustrialLed() { // 初始化控件样式 InitializeComponent(); // 设置控件为双缓冲,防止闪烁 this.DoubleBuffered = true; this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true); // 初始化闪烁定时器 _flashTimer = new Timer(); _flashTimer.Tick += FlashTimer_Tick; } #endregion #region 私有方法 /// <summary> /// 更新闪烁定时器状态 /// </summary> private void UpdateFlashTimer() { if (_enableFlash && (_currentStatus == LedStatus.Fault || _currentStatus == LedStatus.Warning)) { _flashTimer.Interval = FlashInterval; _flashTimer.Start(); } else { _flashTimer.Stop(); _isFlashVisible = true; // 停止闪烁时恢复显示 Invalidate(); } } /// <summary> /// 闪烁定时器触发事件 /// </summary> private void FlashTimer_Tick(object sender, EventArgs e) { _isFlashVisible = !_isFlashVisible; Invalidate(); // 重绘控件实现闪烁 } /// <summary> /// 根据当前状态获取对应颜色 /// </summary> private Color GetCurrentColor() { return _currentStatus switch { LedStatus.Running => _runningColor, LedStatus.Fault => _faultColor, LedStatus.Warning => _warningColor, LedStatus.Standby => _standbyColor, _ => _standbyColor }; } #endregion #region 重绘控件(核心:绘制圆形指示灯) /// <summary> /// 重写OnPaint方法,绘制工控指示灯 /// </summary> protected override void onPaint(PaintEventArgs e) { base.onPaint(e); // 获取绘图对象并设置高质量渲染 Graphics g = e.Graphics; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; // 抗锯齿,使圆形更平滑 // 定义指示灯矩形区域(居中显示,适配控件大小) int ledSize = Math.Min(this.Width, this.Height) - 4; // 留2px边距 Rectangle ledRect = new Rectangle( (this.Width - ledSize) / 2, (this.Height - ledSize) / 2, ledSize, ledSize ); // 获取当前状态颜色 Color currentColor = GetCurrentColor(); // 绘制指示灯背景(阴影效果,增强立体感) using (var shadowBrush = new SolidBrush(Color.FromArgb(50, Color.Black))) { g.FillEllipse(shadowBrush, ledRect.X + 2, ledRect.Y + 2, ledRect.Width, ledRect.Height); } // 绘制指示灯主体(圆形) if (_isFlashVisible) // 闪烁状态下控制显示/隐藏 { using (var ledBrush = new SolidBrush(currentColor)) { g.FillEllipse(ledBrush, ledRect); } // 绘制指示灯边框(增强质感) using (var pen = new Pen(Color.FromArgb(100, Color.Black), 1)) { g.DrawEllipse(pen, ledRect); } // 绘制高光效果(模拟灯光反光,更真实) using (var highlightBrush = new SolidBrush(Color.FromArgb(80, Color.White))) { int highlightSize = ledSize / 3; Rectangle highlightRect = new Rectangle( ledRect.X + ledSize / 5, ledRect.Y + ledSize / 5, highlightSize, highlightSize ); g.FillEllipse(highlightBrush, highlightRect); } } else { // 闪烁隐藏时,绘制透明背景(仅显示边框阴影) using (var pen = new Pen(Color.Transparent)) { g.DrawEllipse(pen, ledRect); } } } #endregion #region 设计时初始化(自动生成,无需手动修改) private void InitializeComponent() { this.SuspendLayout(); // // IndustrialLed // this.Name = "IndustrialLed"; this.Size = new System.Drawing.Size(50, 50); // 默认大小50x50 this.ResumeLayout(false); } #endregion }}2. 控件使用方法
步骤 1:添加控件到窗体
- 编译上述代码,在 Visual Studio 的 “工具箱” 中会自动出现IndustrialLed控件(或手动右键工具箱→选择项→浏览→添加编译后的程序集)
- 拖拽IndustrialLed控件到 WinForms 窗体上,可调整大小(保持正方形效果更佳)
步骤 2:代码控制指示灯状态
using System;using System.Windows.Forms;using IndustrialControls;namespace IndustrialLedDemo{ public partial class FrmMain : Form { public FrmMain() { InitializeComponent(); } // 示例:切换到运行状态 private void btnRunning_Click(object sender, EventArgs e) { industrialLed1.CurrentStatus = IndustrialLed.LedStatus.Running; industrialLed1.EnableFlash = false; // 运行状态不闪烁 } // 示例:切换到故障状态(启用闪烁) private void btnFault_Click(object sender, EventArgs e) { industrialLed1.CurrentStatus = IndustrialLed.LedStatus.Fault; industrialLed1.EnableFlash = true; // 故障状态启用闪烁 industrialLed1.FlashInterval = 300; // 自定义闪烁间隔300ms } // 示例:切换到警告状态 private void btnWarning_Click(object sender, EventArgs e) { industrialLed1.CurrentStatus = IndustrialLed.LedStatus.Warning; industrialLed1.EnableFlash = true; } // 示例:切换到待机状态 private void btnStandby_Click(object sender, EventArgs e) { industrialLed1.CurrentStatus = IndustrialLed.LedStatus.Standby; industrialLed1.EnableFlash = false; } // 示例:自定义指示灯颜色 private void btnCustomColor_Click(object sender, EventArgs e) { industrialLed1.RunningColor = Color.Cyan; // 自定义运行状态为青色 industrialLed1.FaultColor = Color.Magenta; // 自定义故障状态为洋红 industrialLed1.CurrentStatus = IndustrialLed.LedStatus.Running; } }}三、关键特性说明
- 多状态支持:内置Standby(待机)、Running(运行)、Fault(故障)、Warning(警告)四种常用状态,可直接扩展枚举添加自定义状态(如Stop、CommError等)
- 自定义颜色:每个状态对应颜色均可通过属性面板或代码修改,适配不同工控系统的 UI 风格
- 闪烁效果:仅故障 / 警告状态支持闪烁(可启用 / 禁用),闪烁间隔可自定义,通过Timer实现高效闪烁,无界面卡顿
- 立体感设计:通过阴影、高光效果,模拟真实工控指示灯的视觉质感,抗锯齿处理让圆形更平滑
- 高可复用性:继承UserControl,可直接拖拽使用,支持设计时编辑属性,无需重复编写绘制逻辑
四、扩展说明
- 添加文字提示:可在OnPaint方法中添加文字绘制逻辑,显示状态名称(如 “运行”、“故障”)
- 支持椭圆形 / 方形:修改FillEllipse(圆形)为FillRectangle(方形)或FillEllipse(椭圆形,调整矩形宽高比)即可
- 串口 / 网口联动:在工控项目中,可将控件状态与串口(SerialPort)、网口(Socket)接收的数据绑定,实现设备状态实时显示
总结
- 核心实现:通过UserControl+OnPaint重绘,实现圆形工控指示灯,支持状态切换与颜色自定义
- 关键功能:闪烁效果(Timer控件)、立体感(阴影 + 高光)、抗锯齿(平滑圆形)
- 使用便捷:可拖拽使用,支持设计时属性编辑,代码调用简单,可直接集成到工控 WinForms 项目中

