using Dapper; using Microsoft.Win32; using Modbus.Device; using MySql.Data.MySqlClient; using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime; using Sunny.UI; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Timers; using System.Windows.Forms; using 全自动水压检测仪.Data; using 全自动水压检测仪.DATA; using 材料热传导系数; namespace 全自动水压检测仪 { public partial class NormalTemperatureMode : UIForm { BoolSignal boolSignal1 = new BoolSignal(); private Coeffiicientsetting _coeffiicientsetting; private ScanImport _scanImport; private StatusSettingsForm _statusSettingsForm; // 新增状态设置窗体 private ChartManager _chartManager; // 图表管理器 public List CurrentReport; private Report _report; private Stopwatch pressStopwatch; private const int LONG_PRESS_THRESHOLD = 1000; // 1000毫秒=1秒 #region 私有字段 private TcpClient _tcpClient => ModbusResourceManager.Instance.TcpClient; private IModbusMaster _modbusMaster => ModbusResourceManager.Instance.ModbusMaster; #endregion Function ma; DataChange c; private System.Windows.Forms.Timer _readTimer; private System.Windows.Forms.Timer _readTimerTwo; // 第二个定时器引用 private System.Windows.Forms.Timer _readTimetCompareResult; // 第二个定时器引用 private bool _isManualInput = false; // 手动输入标记 private bool _isSwitchingWindow = false; // 窗口切换标记,避免并发 // 温度模式状态跟踪(用于防抖优化) private bool _lastHighTempMode = false; private bool _lastLowTempMode = false; private ConductivityRepository _repository; #region 报警监控相关字段和属性 // 报警寄存器地址定义(根据图片内容) private const ushort PRESSURE_PROTECTION_ADDR = 10200; // M200 压力保护大于 private const ushort TEMPERATURE_PROTECTION_ADDR = 10205; // M205 温度保护大于 private const ushort HIGH_TEMP_LEVEL_LIMIT_ADDR = 10230; // M230 高温液位极限大于 private const ushort NORMAL_TEMP_LEVEL_LIMIT_ADDR = 10235; // M235 常温液位极限大于 private const ushort HIGH_TEMP_LEVEL_MAX_ADDR = 10210; // M210 高温液位上限大于 private const ushort NORMAL_TEMP_LEVEL_MAX_ADDR = 10215; // M215 常温液位上限大于 // 报警状态记录 private Dictionary _alarmStatus = new Dictionary { { PRESSURE_PROTECTION_ADDR, false }, { TEMPERATURE_PROTECTION_ADDR, false }, { HIGH_TEMP_LEVEL_LIMIT_ADDR, false }, { NORMAL_TEMP_LEVEL_LIMIT_ADDR, false }, { HIGH_TEMP_LEVEL_MAX_ADDR, false }, { NORMAL_TEMP_LEVEL_MAX_ADDR, false } }; // 报警描述映射 private Dictionary _alarmDescriptions = new Dictionary { { PRESSURE_PROTECTION_ADDR, "压力保护报警" }, { TEMPERATURE_PROTECTION_ADDR, "温度保护报警" }, { HIGH_TEMP_LEVEL_LIMIT_ADDR, "高温液位极限报警" }, { NORMAL_TEMP_LEVEL_LIMIT_ADDR, "常温液位极限报警" }, { HIGH_TEMP_LEVEL_MAX_ADDR, "高温液位上限报警" }, { NORMAL_TEMP_LEVEL_MAX_ADDR, "常温液位上限报警" } }; // 报警定时器 private System.Windows.Forms.Timer _alarmMonitorTimer; private bool _isCheckingAlarm = false; #endregion public NormalTemperatureMode() { InitializeComponent(); pressStopwatch = new Stopwatch(); // 只创建定时器,不在构造器中启动,避免在 Load 前访问未初始化的资源 _readTimer = InitTimer(); // 保存引用 _readTimerTwo = InitTimerTwo(); // 保存第二个定时器引用 _readTimetCompareResult = InitTimerCompare(); // 初始化报警监控定时器 _alarmMonitorTimer = InitAlarmMonitorTimer(); _repository = new ConductivityRepository(); CurrentReport = new List(); // 初始化图表管理器 _chartManager = new ChartManager(); } private System.Windows.Forms.Timer InitAlarmMonitorTimer() { var timer = new System.Windows.Forms.Timer() { Interval = 2000 // 每2秒检查一次报警 }; timer.Tick += async (s, e) => { // 检查窗体和资源状态 if (this.IsDisposed || !this.IsHandleCreated || _isCheckingAlarm || _modbusMaster == null) { return; } try { await CheckAlarmStatusAsync(); } catch (Exception ex) { Debug.WriteLine($"报警监控异常: {ex.Message}"); } }; return timer; } private async Task CheckAlarmStatusAsync() { if (_isCheckingAlarm) return; // 检查窗体和Modbus连接状态 if (this.IsDisposed || !this.IsHandleCreated || _modbusMaster == null) { return; } _isCheckingAlarm = true; try { // 批量读取所有报警点的状态 var alarmAddresses = new List { PRESSURE_PROTECTION_ADDR, TEMPERATURE_PROTECTION_ADDR, HIGH_TEMP_LEVEL_LIMIT_ADDR, NORMAL_TEMP_LEVEL_LIMIT_ADDR, HIGH_TEMP_LEVEL_MAX_ADDR, NORMAL_TEMP_LEVEL_MAX_ADDR }; foreach (var address in alarmAddresses) { // 每次循环都检查窗体状态 if (this.IsDisposed || !this.IsHandleCreated || _modbusMaster == null) { break; } try { bool[] alarmStatus = await Task.Run(() => { // 再次检查,避免在后台线程中访问已释放的资源 if (_modbusMaster == null) { return null; } try { // 注意:ReadCoils的参数是起始地址和数量 return _modbusMaster.ReadCoils(1, address, 1); } catch { return null; } }); if (alarmStatus != null && alarmStatus.Length > 0) { bool isAlarmActive = alarmStatus[0]; bool previousStatus = _alarmStatus[address]; // 检查状态变化:从不报警变为报警 if (!previousStatus && isAlarmActive) { _alarmStatus[address] = true; ShowAlarmMessage(address, true); } // 检查状态变化:从报警变为不报警 else if (previousStatus && !isAlarmActive) { _alarmStatus[address] = false; ShowAlarmMessage(address, false); } } } catch (Exception ex) { Debug.WriteLine($"读取地址{address}报警状态失败: {ex.Message}"); } // 短暂延迟避免频繁访问 await Task.Delay(100); } } catch (Exception ex) { Debug.WriteLine($"报警检查失败: {ex.Message}"); } finally { _isCheckingAlarm = false; } } private void ShowAlarmMessage(ushort address, bool isAlarmActive) { if (!_alarmDescriptions.ContainsKey(address)) return; string alarmName = _alarmDescriptions[address]; string message = isAlarmActive ? $"{alarmName}已触发!请立即检查设备状态。" : $"{alarmName}已解除。"; string title = isAlarmActive ? "⚠️ 报警触发" : "✅ 报警解除"; SafeInvoke(() => { try { // 使用MessageBox显示报警 if (isAlarmActive) { // 报警触发使用警告图标 MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { // 报警解除使用信息图标 MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Information); } } catch (Exception ex) { Debug.WriteLine($"显示报警消息失败: {ex.Message}"); } }); } private void SafeInvoke(Action action) { if (action == null) return; // 检查窗体是否已释放/句柄是否创建 if (this.IsDisposed || !this.IsHandleCreated) { Debug.WriteLine("窗体已释放或句柄未创建,跳过UI操作"); return; } try { // 如果已经在UI线程,直接执行;否则Invoke if (this.InvokeRequired) { this.Invoke(action); } else { action(); } } catch (ObjectDisposedException ex) { Debug.WriteLine($"UI操作时控件已释放: {ex.Message}"); } catch (InvalidOperationException ex) { Debug.WriteLine($"UI操作异常: {ex.Message}"); } } // 重载:支持BeginInvoke(异步UI更新) private void SafeBeginInvoke(Action action) { if (action == null) return; if (this.IsDisposed || !this.IsHandleCreated) { Debug.WriteLine("窗体已释放或句柄未创建,跳过异步UI操作"); return; } try { if (this.InvokeRequired) { this.BeginInvoke(action); } else { action(); } } catch (ObjectDisposedException ex) { Debug.WriteLine($"异步UI操作时控件已释放: {ex.Message}"); } catch (InvalidOperationException ex) { Debug.WriteLine($"异步UI操作异常: {ex.Message}"); } } private System.Windows.Forms.Timer InitTimer() { var timer = new System.Windows.Forms.Timer() { Interval = 1000 }; timer.Tick += async (s, e) => { if (!_isManualInput && _modbusMaster != null) { try { await ReadLeakTestParametersAsync(); } catch { } } }; // 不在此处 Start return timer; } private System.Windows.Forms.Timer InitTimerTwo() { var timer = new System.Windows.Forms.Timer() { Interval = 1000 }; timer.Tick += async (s, e) => { if (!_isManualInput && _modbusMaster != null) { try { await ReadLeakTestParametersAsyncTwo(); } catch { } } }; // 不在此处 Start return timer; } bool? isValid = null; private System.Windows.Forms.Timer InitTimerCompare() { var timer = new System.Windows.Forms.Timer() { Interval = 1000 }; timer.Tick += async (s, e) => { if (!_isManualInput && _modbusMaster != null) { try { //2 float settingValue = 0, currentValue = 0; float.TryParse(uiTextBox11.Text, out settingValue); float.TryParse(uiLabel22.Text, out currentValue); if (currentValue > settingValue) { isValid = false; _modbusMaster.WriteSingleCoil(1, 10082, true); timer?.Stop(); MessageBox.Show("实验已达到设置压差,自动停止!"); } else { isValid = true; } } catch { } } }; // 不在此处 Start return timer; } private async Task ReadLeakTestParametersAsync() { // 检查窗体状态 if (this.IsDisposed || !this.IsHandleCreated) { return; } // 检查连接状态 if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null) { return; // 静默返回,不显示消息框 } try { var modbusData = await Task.Run(() => { try { return new { //读取所需要的寄存器(同步操作,但在后台线程) Real1 = SafelyReadRegisters(1, 3130, 2),// 实时压力 Real2 = SafelyReadRegisters(1, 3080, 2),// 常温实时液位 Real3 = SafelyReadRegisters(1, 2100, 2),// 初始化压力 Real4 = SafelyReadRegisters(1, 2102, 2),// 结束压力 Real5 = SafelyReadRegisters(1, 2104, 2),// 压差 Real6 = SafelyReadRegisters(1, 2082, 2),// 计时s Real7 = SafelyReadRegisters(1, 2084, 2),// 计时min Real8 = SafelyReadRegisters(1, 2086, 2),// 计时h Real9 = SafelyReadRegisters(1, 3030, 2),// 高温实时液位 Real10 = SafelyReadRegisters(1, 3480, 2),// 箱体温度 Real11 = SafelyReadRegisters(1, 3180, 2),// 出口温度 Real12 = SafelyReadRegisters(1, 2400, 2),// 压力设定值 Real13 = SafelyReadRegisters(1, 3484, 2),// 温度保护 Real14 = SafelyReadRegisters(1, 3134, 2),// 压力保护 Real15 = SafelyReadRegisters(1, 2406, 1),// 时间 CurrentTime = DateTime.Now }; } catch { return null; // 读取失败返回 null } }); // 检查是否成功读取 if (modbusData == null) { throw new InvalidOperationException("Modbus数据读取失败"); } // 检查数据转换工具是否可用 if (c == null) { throw new InvalidOperationException("数据转换工具未初始化"); } // 使用安全的异步UI更新方法 SafeBeginInvoke(() => { try { // 时间显示 if (uiLabel5 != null && !uiLabel5.IsDisposed) uiLabel5.Text = modbusData.CurrentTime.ToString("yyyy-MM-dd HH:mm:ss"); // 实时压力 if (uiLabel28 != null && !uiLabel28.IsDisposed && modbusData.Real1 != null && modbusData.Real1.Length >= 2) { var value0 = c.UshortToFloat(modbusData.Real1[1], modbusData.Real1[0]); uiLabel28.Text = value0.ToString("F2"); } // 常温实时液位 if (uiLabel12 != null && !uiLabel12.IsDisposed && modbusData.Real2 != null && modbusData.Real2.Length >= 2) { var value1 = c.UshortToFloat(modbusData.Real2[1], modbusData.Real2[0]); float percentage = (value1 / 150f) * 100f; // 限制百分比在0-100之间 if (percentage < 0) percentage = 0; if (percentage > 100) percentage = 100; // 更新进度条 if (uiProcessBar1 != null && !uiProcessBar1.IsDisposed) uiProcessBar1.Value = (int)percentage; uiLabel12.Text = value1.ToString("F2"); } // 初始压力 if (uiLabel14 != null && !uiLabel14.IsDisposed && modbusData.Real3 != null && modbusData.Real3.Length >= 2) { var value2 = c.UshortToFloat(modbusData.Real3[1], modbusData.Real3[0]); uiLabel14.Text = value2.ToString("F2"); } // 结束压力 if (uiLabel19 != null && !uiLabel19.IsDisposed && modbusData.Real4 != null && modbusData.Real4.Length >= 2) { var value3 = c.UshortToFloat(modbusData.Real4[1], modbusData.Real4[0]); uiLabel19.Text = value3.ToString("F2"); } // 压差 if (uiLabel22 != null && !uiLabel22.IsDisposed && modbusData.Real5 != null && modbusData.Real5.Length >= 2) { var value4 = c.UshortToFloat(modbusData.Real5[1], modbusData.Real5[0]); uiLabel22.Text = value4.ToString("F2"); } // 合并显示时间(格式:hh:mm:ss) if (uiLabel9 != null && !uiLabel9.IsDisposed) { // 使用0作为缺省值 int seconds = (modbusData.Real6 != null && modbusData.Real6.Length >= 1) ? modbusData.Real6[0] : 0; int minutes = (modbusData.Real7 != null && modbusData.Real7.Length >= 1) ? modbusData.Real7[0] : 0; int hours = (modbusData.Real8 != null && modbusData.Real8.Length >= 1) ? modbusData.Real8[0] : 0; // 格式化为00:00:00 string timeString = $"{hours:D2}:{minutes:D2}:{seconds:D2}"; uiLabel9.Text = timeString; } // 高温实时液位 if (uiLabel7 != null && !uiLabel7.IsDisposed && modbusData.Real9 != null && modbusData.Real9.Length >= 2) { var value8 = c.UshortToFloat(modbusData.Real9[1], modbusData.Real9[0]); float percentage = (value8 / 150f) * 100f; // 限制百分比在0-100之间 if (percentage < 0) percentage = 0; if (percentage > 100) percentage = 100; // 更新进度条 if (uiProcessBar2 != null && !uiProcessBar2.IsDisposed) uiProcessBar2.Value = (int)percentage; uiLabel7.Text = value8.ToString("F2"); } // 箱体温度 if (uiLabel42 != null && !uiLabel42.IsDisposed && modbusData.Real10 != null && modbusData.Real10.Length >= 2) { var value9 = c.UshortToFloat(modbusData.Real10[1], modbusData.Real10[0]); uiLabel42.Text = value9.ToString("F1"); } // 出口温度 if (uiLabel38 != null && !uiLabel38.IsDisposed && modbusData.Real11 != null && modbusData.Real11.Length >= 2) { var value10 = c.UshortToFloat(modbusData.Real11[1], modbusData.Real11[0]); uiLabel38.Text = value10.ToString("F1"); } // 更新图表数据(实时压力和压力设定值) if (modbusData.Real1 != null && modbusData.Real1.Length >= 2 && modbusData.Real12 != null && modbusData.Real12.Length >= 2) { try { var pressure = c.UshortToFloat(modbusData.Real1[1], modbusData.Real1[0]); var pressureSetValue = c.UshortToFloat(modbusData.Real12[1], modbusData.Real12[0]); // 获取测试时间(从PLC读取的时分秒)并计算总秒数 int seconds = (modbusData.Real6 != null && modbusData.Real6.Length >= 1) ? modbusData.Real6[0] : 0; int minutes = (modbusData.Real7 != null && modbusData.Real7.Length >= 1) ? modbusData.Real7[0] : 0; int hours = (modbusData.Real8 != null && modbusData.Real8.Length >= 1) ? modbusData.Real8[0] : 0; int totalSeconds = hours * 3600 + minutes * 60 + seconds; _chartManager?.AddDataPoint(pressure, pressureSetValue, totalSeconds); } catch (Exception chartEx) { Debug.WriteLine($"图表更新异常: {chartEx.Message}"); } } // 温度保护 if (uiTextBox12 != null && !uiTextBox12.IsDisposed && modbusData.Real13 != null && modbusData.Real13.Length >= 2) { var protemp = c.UshortToFloat(modbusData.Real13[1], modbusData.Real13[0]); uiTextBox12.Text = protemp.ToString("F1"); } // 压力保护 if (uiTextBox13 != null && !uiTextBox13.IsDisposed && modbusData.Real14 != null && modbusData.Real14.Length >= 2) { var propre = c.UshortToFloat(modbusData.Real14[1], modbusData.Real14[0]); uiTextBox13.Text = propre.ToString("F1"); } // 压力保护 if (uiTextBox14 != null && !uiTextBox14.IsDisposed && modbusData.Real15 != null && modbusData.Real15.Length >= 2) { var propre = modbusData.Real15[0]; uiTextBox14.Text = (propre / 10).ToString("F1"); } } catch (Exception uiEx) { Debug.WriteLine($"UI更新异常: {uiEx.Message}"); } }); } catch (Exception ex) { // 安全地停止定时器 try { _readTimer?.Stop(); } catch { } SafeInvoke(() => { MessageBox.Show($"读取调试参数失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); }); } } bool isAddTag = false; // 辅助方法:安全读取寄存器 private ushort[] SafelyReadRegisters(byte slaveAddress, ushort startAddress, ushort numberOfPoints) { try { if (_modbusMaster != null && _tcpClient.Connected) { return _modbusMaster?.ReadHoldingRegisters(slaveAddress, startAddress, numberOfPoints); } } catch { // 读取失败返回空数组 } return new ushort[numberOfPoints]; // 返回默认值数组 } private string GetStatusText(int statusValue) { switch (statusValue) { case 0: return "空闲中"; case 1: return "水循环中"; case 2: return "加压中"; case 3: return "保压测试中"; case 4: return "空闲中"; // 根据您的要求,4也显示"空闲中" default: return $"未知状态({statusValue})"; } } private async Task ReadLeakTestParametersAsyncTwo() { // 检查窗体状态 if (this.IsDisposed || !this.IsHandleCreated) { return; } //是否连接 if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null) return; //测试步骤 try { ushort[] testslip = await Task.Run(() => _modbusMaster?.ReadHoldingRegisters(1, 2080, 2) ); if (testslip == null || testslip.Length == 0) return; int testvalue = testslip[0]; string statusText = GetStatusText(testvalue); // 使用安全的UI更新方法 SafeInvoke(() => { if (uiLabel3 != null && !uiLabel3.IsDisposed) uiLabel3.Text = statusText; }); } catch (Exception ex) { Debug.WriteLine($"[错误] 读取测试步(地址80)失败: {ex.Message}"); } //压力设定 try { ushort[] registers = await Task.Run(() => _modbusMaster?.ReadHoldingRegisters(1, 2400, 2) ); if (registers == null || registers.Length == 0) return; float pressureValue = c.UshortToFloat(registers[1], registers[0]); SafeInvoke(() => { if (uiTextBox1 != null && !uiTextBox1.IsDisposed) uiTextBox1.Text = pressureValue.ToString("F2"); }); } catch (Exception ex) { Debug.WriteLine($"[错误] 读取压力设定(地址400)失败: {ex.Message}"); } //箱体温度 try { ushort[] registers = await Task.Run(() => _modbusMaster?.ReadHoldingRegisters(1, 2402, 2) ); if (registers == null || registers.Length == 0) return; float registerValue = c.UshortToFloat(registers[1], registers[0]); SafeInvoke(() => { if (uiTextBox4 != null && !uiTextBox4.IsDisposed) uiTextBox4.Text = registerValue.ToString("F2"); }); } catch (Exception ex) { Debug.WriteLine($"[错误] 读取箱体温度(地址402)失败: {ex.Message}"); } //保压时间 try { ushort[] registers = await Task.Run(() => _modbusMaster?.ReadHoldingRegisters(1, 2404, 2) ); if (registers == null || registers.Length == 0) return; int pressureValue = registers[0]; SafeInvoke(() => { if (uiTextBox5 != null && !uiTextBox5.IsDisposed) uiTextBox5.Text = pressureValue.ToString(); }); } catch (Exception ex) { Debug.WriteLine($"[错误] 读取保压时间设置(地址404)失败: {ex.Message}"); } //出口温度设置 try { ushort[] registers = Task.Run(() => _modbusMaster?.ReadHoldingRegisters(1, 2412, 2) ).Result; if (registers == null || registers.Length == 0) return; float temperatureValue = c.UshortToFloat(registers[1], registers[0]); SafeInvoke(() => { if (uiTextBox9 != null && !uiTextBox9.IsDisposed) uiTextBox9.Text = temperatureValue.ToString("F2"); }); } catch (Exception ex) { Debug.WriteLine($"[错误] 读取出口温度设置(地址412)失败: {ex.Message}"); } try { // 所有Modbus读取操作移到后台线程 var modbusResults = await Task.Run(() => { try { return new { TestStatus = _modbusMaster?.ReadCoils(1, 10081, 1), ButtonStatus = _modbusMaster?.ReadCoils(1, 10030, 1), LowStatus = _modbusMaster?.ReadCoils(1, 10031, 1), HighStatus = _modbusMaster?.ReadCoils(1, 10032, 1), Valve2 = _modbusMaster?.ReadCoils(1, 10008, 1), Valve13 = _modbusMaster?.ReadCoils(1, 10001, 1), Valve3 = _modbusMaster?.ReadCoils(1, 10006, 1), Valve4 = _modbusMaster?.ReadCoils(1, 10013, 1), Valve5 = _modbusMaster?.ReadCoils(1, 10005, 1), Valve6 = _modbusMaster?.ReadCoils(1, 10007, 1), Valve7 = _modbusMaster?.ReadCoils(1, 10004, 1), Valve8 = _modbusMaster?.ReadCoils(1, 10010, 1), Valve9 = _modbusMaster?.ReadCoils(1, 10012, 1), Valve10 = _modbusMaster?.ReadCoils(1, 10009, 1), Valve12 = _modbusMaster?.ReadCoils(1, 10004, 1) }; } catch (Exception ex) { Debug.WriteLine($"Modbus读取阀门状态失败: {ex.Message}"); return null; } }); if (modbusResults == null) return; // 统一用SafeInvoke更新所有UI控件 SafeInvoke(() => { //测试按键 if (modbusResults.TestStatus != null && modbusResults.TestStatus.Length > 0) { if (uiButton2 != null && !uiButton2.IsDisposed) { if (modbusResults.TestStatus[0]) { uiButton2.Text = "测试中"; uiButton2.ForeColor = System.Drawing.Color.Red; boolSignal1.Value = true; boolSignal1.CheckRisingEdge(); } else { uiButton2.Text = "启动测试"; uiButton2.ForeColor = System.Drawing.Color.White; boolSignal1.CheckRisingEdge(); boolSignal1.Value = false; } } } //高低温切换 if (modbusResults.ButtonStatus != null && modbusResults.ButtonStatus.Length > 0 && uiSwitch1 != null && !uiSwitch1.IsDisposed) { bool newSwitchState = modbusResults.ButtonStatus[0]; bool currentSwitchState = uiSwitch1.Active; // 只有状态真正改变时才更新 if (newSwitchState != currentSwitchState) { uiSwitch1.Active = newSwitchState; } } //低温指示(优化版本 - 减少不必要的UI更新) if (modbusResults.LowStatus != null && modbusResults.LowStatus.Length > 0 && uiLight1 != null && !uiLight1.IsDisposed) { bool currentLowTempState = modbusResults.LowStatus[0]; uiLight1.State = currentLowTempState ? UILightState.On : UILightState.Off; // 只有状态真正改变时才更新控件可见性 if (_lastLowTempMode != currentLowTempState) { _lastLowTempMode = currentLowTempState; UpdateControlsVisibilityByMode(); } } //高温指示(优化版本 - 减少不必要的UI更新) if (modbusResults.HighStatus != null && modbusResults.HighStatus.Length > 0 && uiLight2 != null && !uiLight2.IsDisposed) { bool currentHighTempState = modbusResults.HighStatus[0]; uiLight2.State = currentHighTempState ? UILightState.On : UILightState.Off; // 只有状态真正改变时才更新控件可见性 if (_lastHighTempMode != currentHighTempState) { _lastHighTempMode = currentHighTempState; UpdateControlsVisibilityByMode(); } } //高压进阀指示 if (modbusResults.Valve2 != null && modbusResults.Valve2.Length > 0 && uiLight4 != null && !uiLight4.IsDisposed) { uiLight4.State = modbusResults.Valve2[0] ? UILightState.On : UILightState.Off; } //高压出阀 if (modbusResults.Valve13 != null && modbusResults.Valve13.Length > 0 && uiLight3 != null && !uiLight3.IsDisposed) { uiLight3.State = modbusResults.Valve13[0] ? UILightState.On : UILightState.Off; } //常温抽水阀指示 if (modbusResults.Valve3 != null && modbusResults.Valve3.Length > 0 && uiLight5 != null && !uiLight5.IsDisposed) { uiLight5.State = modbusResults.Valve3[0] ? UILightState.On : UILightState.Off; } //常温水箱加水指示 if (modbusResults.Valve4 != null && modbusResults.Valve4.Length > 0) { if (uiLight6 != null && !uiLight6.IsDisposed) uiLight6.State = modbusResults.Valve4[0] ? UILightState.On : UILightState.Off; if (uiButton13 != null && !uiButton13.IsDisposed) { if (modbusResults.Valve4[0]) { uiButton13.ForeColor = Color.Red; uiButton13.Text = "常温加水中"; } else { uiButton13.ForeColor = Color.White; uiButton13.Text = "常温加水"; } } } //高温抽水阀指示 if (modbusResults.Valve5 != null && modbusResults.Valve5.Length > 0 && uiLight7 != null && !uiLight7.IsDisposed) { uiLight7.State = modbusResults.Valve5[0] ? UILightState.On : UILightState.Off; } //空气抽气阀指示 if (modbusResults.Valve6 != null && modbusResults.Valve6.Length > 0 && uiLight8 != null && !uiLight8.IsDisposed) { uiLight8.State = modbusResults.Valve6[0] ? UILightState.On : UILightState.Off; } //加热状态指示 if (modbusResults.Valve7 != null && modbusResults.Valve7.Length > 0 && uiLight9 != null && !uiLight9.IsDisposed) { uiLight9.State = modbusResults.Valve7[0] ? UILightState.On : UILightState.Off; } //常温回水阀指示 if (modbusResults.Valve8 != null && modbusResults.Valve8.Length > 0 && uiLight10 != null && !uiLight10.IsDisposed) { uiLight10.State = modbusResults.Valve8[0] ? UILightState.On : UILightState.Off; } //高温水箱加水指示 if (modbusResults.Valve9 != null && modbusResults.Valve9.Length > 0) { if (uiLight11 != null && !uiLight11.IsDisposed) uiLight11.State = modbusResults.Valve9[0] ? UILightState.On : UILightState.Off; if (uiButton5 != null && !uiButton5.IsDisposed) { if (modbusResults.Valve9[0]) { uiButton5.ForeColor = Color.Red; uiButton5.Text = "高温加水中"; } else { uiButton5.ForeColor = Color.White; uiButton5.Text = "高温加水"; } } } //高温回水阀指示 if (modbusResults.Valve10 != null && modbusResults.Valve10.Length > 0 && uiLight12 != null && !uiLight12.IsDisposed) { uiLight12.State = modbusResults.Valve10[0] ? UILightState.On : UILightState.Off; } //水箱加热指示 if (modbusResults.Valve12 != null && modbusResults.Valve12.Length > 0 && uiButton4 != null && !uiButton4.IsDisposed) { if (modbusResults.Valve12[0]) { uiButton4.ForeColor = Color.Red; uiButton4.Text = "加热中"; } else { uiButton4.ForeColor = Color.White; uiButton4.Text = "水箱加热"; } } // 更新温度模式 // uiLabel11 已移除,温度模式通过 uiSwitch1 切换按钮显示 }); } catch (Exception ex) { Debug.WriteLine($"[错误] 读取阀门状态失败: {ex.Message}"); } } private void NormalTemperatureMode_Load(object sender, EventArgs e) { // 权限检查:只有管理员才能看到"录入系统"按钮 if (!LoginData.IsAdmin()) { // 普通用户隐藏"录入系统"按钮 uiButton7.Visible = false; // 调试输出 System.Diagnostics.Debug.WriteLine($"[NormalTemperatureMode] 普通用户登录,隐藏录入系统按钮"); } else { // 管理员显示"录入系统"按钮 uiButton7.Visible = true; // 调试输出 System.Diagnostics.Debug.WriteLine($"[NormalTemperatureMode] 管理员登录,显示录入系统按钮"); } string plcIp = "192.168.1.10"; //string plcIp = "127.0.0.1"; bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502); if (!initSuccess) { MessageBox.Show("连接Modbus服务器失败!", "错误"); this.Close(); return; } // 检查连接状态 if (_tcpClient == null || !_tcpClient.Connected) { MessageBox.Show("Modbus连接异常!", "错误"); this.Close(); return; } ma = new Function(_modbusMaster); c = new DataChange(); // 暂时注释 _modbusMaster?.WriteSingleCoil(1, 10030, false); boolSignal1.OnRisingEdge += BoolSignal1_OnRisingEdge; // 初始化图表 try { _chartManager.InitializeChart(uiPanel_ChartPlaceholder); Debug.WriteLine("[NormalTemperatureMode] 图表初始化成功"); } catch (Exception ex) { Debug.WriteLine($"[NormalTemperatureMode] 图表初始化失败: {ex.Message}"); } //float pressValue = 0; //float.TryParse(uiTextBox11.Text, out pressValue); uiTextBox2.Text = lldh; uiTextBox10.Text = jh; uiTextBox11.Text = diffpress.ToString("F2"); // 在 Load 完成初始化后再启动定时器,避免定时器在 c / ma 未就绪时触发访问导致异常 //_readTimer?.Start(); //_readTimerTwo?.Start(); } void BoolSignal1_OnRisingEdge() { if (isAddTag) return; // 使用SafeInvoke确保UI读取操作在UI线程执行 SafeInvoke(() => { uiTextBox3.Text = uiLabel14.Text;//初始压力 uiTextBox8.Text = uiTextBox5.Text;//保压时间 uiTextBox6.Text = uiLabel22.Text;//压差 uiTextBox7.Text = uiLabel19.Text;//结束压力 // 获取联络单号和件号 string contactNumber = uiTextBox2.Text.Trim(); string itemNumber = uiTextBox10.Text.Trim(); // 组合条码用于兼容性 string barcode = $"{contactNumber}-{itemNumber}"; CurrentReport.Add(new ConductivityTestData { barcode = barcode, //ContactNumber = contactNumber, //ItemNumber = itemNumber, CreateTime = DateTime.Now, diffpressure = uiTextBox6.Text.ToDouble(), dwelltime = uiTextBox8.Text.ToDouble(), temperature = uiTextBox4.Text.ToDouble(), endpressure = uiTextBox7.Text.ToDouble(), startpressure = uiTextBox3.Text.ToDouble(), Type = uiLight1.State == UILightState.On ? 1 : 0, //新增 kzh = kzh, jh = uiTextBox10.Text, endtime = DateTime.Now, quantity = quantity, lldh = uiTextBox2.Text, standarderror = standarderror, starttime = starttime, testresult = (isValid ?? false) ? "合格" : "不合格" }); _repository.InsertReportItems(new ConductivityTestData { barcode = barcode, CreateTime = DateTime.Now, diffpressure = uiTextBox6.Text.ToDouble(), dwelltime = uiTextBox8.Text.ToDouble(), temperature = uiTextBox4.Text.ToDouble(), endpressure = uiTextBox7.Text.ToDouble(), startpressure = uiTextBox3.Text.ToDouble(), Type = uiLight1.State == UILightState.On ? 1 : 0, //新增 kzh = kzh, jh = uiTextBox10.Text, endtime = DateTime.Now, quantity = quantity, lldh = uiTextBox2.Text, standarderror = standarderror, starttime = starttime, testresult = (isValid ?? false) ? "合格" : "不合格" }); //uiTextBox2.Text = string.Empty; //uiTextBox10.Text = string.Empty; }); isAddTag = true; _readTimetCompareResult?.Stop(); } private bool TryReconnect() { try { string plcIp = "192.168.1.10"; //string plcIp = "127.0.0.1"; bool initSuccess = Data.ModbusResourceManager.Instance.Init(plcIp, 502); if (initSuccess) { ma = new Function(_modbusMaster); return true; } } catch (Exception ex) { Debug.WriteLine($"[错误] 重连失败: {ex.Message}"); } return false; } //private void SwitchWindow(ref T windowInstance, Func createFunc) where T : UIForm //{ // _isSwitchingWindow = true; // _readTimer?.Stop(); // _readTimerTwo?.Stop(); // 停止第二个定时器 // // 2. 检查资源是否可用(添加重连机制) // if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null) // { // //尝试重新连接 // bool reconnectSuccess = TryReconnect(); // if (!reconnectSuccess) // { // MessageBox.Show("TCP连接已断开,请重新连接!", "提示"); // return; // } // } // // 3. 复用窗口实例:不存在则创建,存在则激活 // if (windowInstance == null || windowInstance.IsDisposed) // { // windowInstance = createFunc(); // windowInstance.FormClosed += (s, e) => // { // this.Invoke(new Action(() => // { // _isSwitchingWindow = false; // _readTimer?.Start(); // _readTimerTwo?.Start(); // 恢复第二个定时器 // this.Show(); // this.Activate(); // })); // }; // } // else // { // windowInstance.Activate(); // return; // } // this.Hide(); // windowInstance.Show(); //} private void SwitchWindow(T windowInstance, Func createFunc) where T : UIForm { _isSwitchingWindow = true; _readTimer?.Stop(); _readTimerTwo?.Stop(); _alarmMonitorTimer?.Stop(); // 检查资源是否可用 if (_tcpClient == null || !_tcpClient.Connected || _modbusMaster == null) { bool reconnectSuccess = TryReconnect(); if (!reconnectSuccess) { SafeInvoke(() => { MessageBox.Show("TCP连接已断开,请重新连接!", "提示"); }); return; } } // 需要将 windowInstance 声明为局部变量 T localInstance = windowInstance; // 复用窗口实例 if (localInstance == null || localInstance.IsDisposed) { localInstance = createFunc(); localInstance.FormClosed += (s, e) => { SafeInvoke(() => { _isSwitchingWindow = false; _readTimer?.Start(); _readTimerTwo?.Start(); _alarmMonitorTimer?.Start(); this.Show(); this.Activate(); }); }; } else { SafeInvoke(() => localInstance.Activate()); return; } SafeInvoke(() => { this.Hide(); localInstance.Show(); }); // 如果需要更新外部引用,可以返回实例 // return localInstance; } private void NormalTemperatureMode_FormClosing(object sender, FormClosingEventArgs e) { try { // 先停止所有定时器,防止在释放资源时继续触发 if (_readTimer != null) { _readTimer.Stop(); _readTimer.Tick -= null; // 移除事件处理器 _readTimer.Dispose(); _readTimer = null; } if (_readTimerTwo != null) { _readTimerTwo.Stop(); _readTimerTwo.Tick -= null; _readTimerTwo.Dispose(); _readTimerTwo = null; } // 停止报警监控定时器 if (_alarmMonitorTimer != null) { _alarmMonitorTimer.Stop(); _alarmMonitorTimer.Tick -= null; _alarmMonitorTimer.Dispose(); _alarmMonitorTimer = null; } // 等待异步操作完成 int waitCount = 0; while (_isCheckingAlarm && waitCount < 10) { System.Threading.Thread.Sleep(100); waitCount++; } // 释放图表资源 try { _chartManager?.Dispose(); _chartManager = null; } catch (Exception ex) { Debug.WriteLine($"释放图表资源失败: {ex.Message}"); } // 释放其他窗体资源 try { _coeffiicientsetting?.Dispose(); _scanImport?.Dispose(); _statusSettingsForm?.Dispose(); _report?.Dispose(); } catch (Exception ex) { Debug.WriteLine($"释放窗体资源失败: {ex.Message}"); } // 仅用户主动关闭时退出应用 if (e.CloseReason == CloseReason.UserClosing) { try { ModbusResourceManager.Instance?.Dispose(); } catch (Exception ex) { Debug.WriteLine($"释放Modbus资源失败: {ex.Message}"); } Application.Exit(); } } catch (Exception ex) { Debug.WriteLine($"窗体关闭异常: {ex.Message}"); // 确保应用能够退出 if (e.CloseReason == CloseReason.UserClosing) { Application.Exit(); } } } private void NormalTemperatureMode_FormClosed_1(object sender, FormClosedEventArgs e) { _coeffiicientsetting?.Dispose(); } //压力设置 private void uiTextBox1_Click(object sender, EventArgs e) { SafeInvoke(() => { ma?.WriteToPLCForNew(uiTextBox1.Text.Trim(), 2400, Function.DataType.浮点型); }); } //测试保压时间设置 private void uiTextBox5_Click(object sender, EventArgs e) { SafeInvoke(() => { ma?.WriteToPLCForNew(uiTextBox5.Text.Trim(), 2404, Function.DataType.整形); }); } #region 按钮控件 //常温加水 private void uiButton13_Click(object sender, EventArgs e) { ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10013); } //隐藏 private void uiButton14_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { pressStopwatch.Restart(); } } private void uiButton14_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { pressStopwatch.Stop(); if (pressStopwatch.ElapsedMilliseconds >= LONG_PRESS_THRESHOLD) { // 执行长按操作 - 打开系数设置 EnterFunction(); } else { // 执行点击操作 - 打开状态设置窗体 OpenStatusSettingsForm(); } } } private void EnterFunction() { // 长按后进入的功能 SwitchWindow(_coeffiicientsetting, () => new Coeffiicientsetting()); } //切换报告界面 private void uiButton1_Click(object sender, EventArgs e) { SwitchWindow(_report, () => new Report(CurrentReport)); } //箱体温度设置 private void uiTextBox4_Click(object sender, EventArgs e) { SafeInvoke(() => { ma?.WriteToPLCForNew(uiTextBox4.Text.Trim(), 2402, Function.DataType.浮点型); }); } DateTime starttime; //启动测试 private void uiButton2_Click(object sender, EventArgs e) { ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10080); isAddTag = false; starttime = DateTime.Now; // 清除图表数据,开始新的测试 _chartManager?.ClearData(); Debug.WriteLine("[NormalTemperatureMode] 启动测试,清除图表数据"); _readTimetCompareResult.Start(); } //停止测试 private void uiButton3_Click(object sender, EventArgs e) { ma?.BtnClickFunctionForNew(Function.ButtonType.复归型, 10082); } //切换实验模式(优化版本 - 减少延迟和卡顿) private async void uiSwitch1_Click(object sender, EventArgs e) { try { // 暂停定时器,避免并发访问Modbus _readTimer?.Stop(); _readTimerTwo?.Stop(); _alarmMonitorTimer?.Stop(); // 在后台线程执行Modbus操作 await Task.Run(() => { try { ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10030); } catch (Exception ex) { Debug.WriteLine($"[uiSwitch1_Click] 切换模式失败: {ex.Message}"); SafeInvoke(() => { MessageBox.Show($"切换模式失败:{ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); }); } }); // 缩短延迟时间,从800ms减少到300ms await Task.Delay(300); // 更新控件可见性(已优化为批量更新) SafeInvoke(() => { UpdateControlsVisibilityByMode(); // 更新图表模式 bool isHighTempMode = uiLight2 != null && uiLight2.State == UILightState.On; _chartManager?.UpdateChartMode(isHighTempMode); }); // 恢复定时器 _readTimer?.Start(); _readTimerTwo?.Start(); _alarmMonitorTimer?.Start(); } catch (Exception ex) { Debug.WriteLine($"[uiSwitch1_Click] 异常: {ex.Message}"); // 确保定时器恢复 _readTimer?.Start(); _readTimerTwo?.Start(); _alarmMonitorTimer?.Start(); } } //出口温度设置 private void uiTextBox9_Click(object sender, EventArgs e) { SafeInvoke(() => { ma?.WriteToPLCForNew(uiTextBox9.Text.Trim(), 2412, Function.DataType.浮点型); }); } //高温加水 private void uiButton5_Click(object sender, EventArgs e) { ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10012); } //高温加热 private void uiButton4_Click(object sender, EventArgs e) { ma?.BtnClickFunctionForNew(Function.ButtonType.切换型, 10004); } //清除报警 private void uiButton6_Click(object sender, EventArgs e) { ma?.BtnClickFunctionForNew(Function.ButtonType.复归型, 10025); // 同时清除本地记录的报警状态 ClearAllAlarms(); } #endregion private void ClearAllAlarms() { // 重置所有报警状态 foreach (var address in _alarmStatus.Keys.ToList()) { _alarmStatus[address] = false; } SafeInvoke(() => { MessageBox.Show("所有报警状态已重置", "提示"); }); } private void NormalTemperatureMode_Shown(object sender, EventArgs e) { if (_modbusMaster != null) { _readTimer.Start(); _readTimerTwo.Start(); if (_alarmMonitorTimer != null) { _alarmMonitorTimer.Start(); } } // 初始化时根据当前模式更新控件可见性 UpdateControlsVisibilityByMode(); } //返回录入系统 private void uiButton7_Click(object sender, EventArgs e) { SwitchWindow(_scanImport, () => new ScanImport()); } private string _currentTemperatureMode = ""; // 保存当前温度模式 private string _currentBarcode = ""; // 保存当前条码 string kzh = string.Empty; int quantity = 0; decimal standarderror = 0; static float diffpress = 0; static string lldh = string.Empty; static string jh = string.Empty; private void uiButton8_Click(object sender, EventArgs e) { try { // 1. 获取联络单号和件号输入(确保在UI线程读取) string contactNumber = ""; string itemNumber = ""; SafeInvoke(() => { contactNumber = uiTextBox2.Text.Trim(); itemNumber = uiTextBox10.Text.Trim(); }); //if (string.IsNullOrEmpty(contactNumber)) //{ // SafeInvoke(() => // { // MessageBox.Show("请输入联络单号!"); // }); // return; //} if (string.IsNullOrEmpty(itemNumber)) { SafeInvoke(() => { MessageBox.Show("请输入件号!"); }); return; } // 组合成完整的条码(联络单号-件号) lldh = uiTextBox2.Text; jh = uiTextBox10.Text; // 2. 从数据库查询数据 ScanData scanData = GetScanDataByBarcode(jh); if (scanData == null) { SafeInvoke(() => { MessageBox.Show($"未找到件号 {itemNumber} 的记录!"); }); return; } kzh = scanData.kzh; quantity = scanData.quantity ?? 0; uiTextBox11.Text = scanData.pressuresetting.ToString(); diffpress = scanData.pressuresetting.Value; standarderror = scanData.standarderror.Value; // 3. 连接到PLC并写入数据 WriteScanDataToPLC(scanData); // 4. 保存当前条码和温度模式 _currentBarcode = string.Empty; //; _currentTemperatureMode = scanData.TemperatureMode.ToString(); // 5. 更新显示 SafeInvoke(() => { // uiLabel11 已移除,温度模式通过 uiSwitch1 切换按钮显示 }); } catch (Exception ex) { SafeInvoke(() => { MessageBox.Show($"操作失败:{ex.Message}"); }); } } private ScanData GetScanDataByBarcode(string jh) { using (var connection = new MySqlConnection(_repository._connectionString)) { connection.Open(); var sql = @"SELECT * FROM scandata WHERE jh = @jh ORDER BY CreateTime DESC LIMIT 1"; return connection.QueryFirstOrDefault(sql, new { jh }); } } private void WriteScanDataToPLC(ScanData data) { // 写入压力到PLC地址2400(浮点型) //ma?.WriteToPLCForNew(data.diffpressure.ToString(), 2400, Function.DataType.浮点型); //// 写入测试保压时间到PLC地址2404(整形) //ma?.WriteToPLCForNew(data.dwelltime.ToString("F0"), 2404, Function.DataType.整形); //// 写入温度到PLC地址2402(浮点型) //ma?.WriteToPLCForNew(data.temperature.ToString(), 2402, Function.DataType.浮点型); //// 写入出口温度到PLC地址2412(浮点型) //ma?.WriteToPLCForNew(data.exit_temperature.ToString(), 2412, Function.DataType.浮点型); // 1. 写入压力到PLC地址2400(浮点型) float pressure = data.diffpressure; ushort[] pressureRegisters = ConvertFloatToRegisters(pressure); _modbusMaster.WriteMultipleRegisters(1, 2400, pressureRegisters); // 2. 写入测试保压时间到PLC地址2404(整形) int dwellTime = (int)data.dwelltime; ushort[] dwellTimeRegisters = ConvertIntToRegisters(dwellTime); _modbusMaster.WriteMultipleRegisters(1, 2404, dwellTimeRegisters); // 3. 写入温度到PLC地址2402(浮点型) float temperature = data.temperature; ushort[] temperatureRegisters = ConvertFloatToRegisters(temperature); _modbusMaster.WriteMultipleRegisters(1, 2402, temperatureRegisters); // 4. 写入出口温度到PLC地址2412(浮点型) float exitTemperature = data.exit_temperature; ushort[] exitTempRegisters = ConvertFloatToRegisters(exitTemperature); _modbusMaster.WriteMultipleRegisters(1, 2412, exitTempRegisters); } // 将浮点数转换为寄存器数组(2个寄存器) private ushort[] ConvertFloatToRegisters(float value) { byte[] bytes = BitConverter.GetBytes(value); ushort[] registers = new ushort[2]; registers[0] = BitConverter.ToUInt16(bytes, 0); // 第一个寄存器(低位) registers[1] = BitConverter.ToUInt16(bytes, 2); // 第二个寄存器(高位) return registers; } // 将整数转换为寄存器数组(2个寄存器) private ushort[] ConvertIntToRegisters(int value) { byte[] bytes = BitConverter.GetBytes(value); ushort[] registers = new ushort[2]; registers[0] = BitConverter.ToUInt16(bytes, 0); // 第一个寄存器(低位) registers[1] = BitConverter.ToUInt16(bytes, 2); // 第二个寄存器(高位) return registers; } /// /// 更新状态设置窗体的显示 /// public void UpdateStatusSettingsForm(StatusSettingsForm form) { if (form == null || form.IsDisposed) return; try { // 更新温度模式状态 var light1State = uiLight1 != null ? uiLight1.State : UILightState.Off; var light2State = uiLight2 != null ? uiLight2.State : UILightState.Off; var modeText = _currentTemperatureMode ?? ""; form.UpdateTempModeStatus(light1State, light2State, modeText); // 更新阀门状态 form.UpdateValveStatus( uiLight3 != null ? uiLight3.State : UILightState.Off, uiLight4 != null ? uiLight4.State : UILightState.Off, uiLight5 != null ? uiLight5.State : UILightState.Off, uiLight6 != null ? uiLight6.State : UILightState.Off, uiLight7 != null ? uiLight7.State : UILightState.Off, uiLight8 != null ? uiLight8.State : UILightState.Off, uiLight9 != null ? uiLight9.State : UILightState.Off, uiLight10 != null ? uiLight10.State : UILightState.Off, uiLight11 != null ? uiLight11.State : UILightState.Off, uiLight12 != null ? uiLight12.State : UILightState.Off ); } catch (Exception ex) { Debug.WriteLine($"更新状态设置窗体失败: {ex.Message}"); } } /// /// 打开状态设置窗体 /// private void OpenStatusSettingsForm() { if (_statusSettingsForm == null || _statusSettingsForm.IsDisposed) { _statusSettingsForm = new StatusSettingsForm(this); _statusSettingsForm.Show(); } else { _statusSettingsForm.Activate(); } } /// /// 设置按钮点击事件 - 打开状态设置窗体 /// private void uiButton_Settings_Click(object sender, EventArgs e) { OpenStatusSettingsForm(); } public event EventHandler ReturnToLoginRequested; //返回登录 private void uiButton9_Click(object sender, EventArgs e) { // 停止所有操作 _readTimer?.Stop(); _readTimerTwo?.Stop(); _alarmMonitorTimer?.Stop(); // 释放资源 ModbusResourceManager.Instance?.Dispose(); // 直接重新启动应用程序 Application.Restart(); // 关闭当前窗口 Environment.Exit(0); } /// /// /// 根据温度模式更新控件可见性(优化版本 - 批量更新减少卡顿) /// 常温模式:显示常温相关参数(常温实时液位、常温加水) /// 高温模式:显示高温相关参数(高温实时液位、箱体温度、出口温度、高温加水、水箱加热) /// private void UpdateControlsVisibilityByMode() { try { // 判断当前是否为高温模式(uiLight2亮起表示高温模式) bool isHighTempMode = uiLight2 != null && uiLight2.State == UILightState.On; // 暂停布局更新,批量修改控件属性,减少重绘次数 this.SuspendLayout(); // ========== 高温模式专属控件(高温模式显示,常温模式隐藏) ========== // 高温实时液位(mm) if (uiPanel31 != null && !uiPanel31.IsDisposed) uiPanel31.Visible = isHighTempMode; // 箱体温度(°C) if (uiPanel35 != null && !uiPanel35.IsDisposed) uiPanel35.Visible = isHighTempMode; // 出口温度(°C) if (uiPanel33 != null && !uiPanel33.IsDisposed) uiPanel33.Visible = isHighTempMode; // 高温加水按钮 if (uiButton5 != null && !uiButton5.IsDisposed) uiButton5.Visible = isHighTempMode; // 高温加水指示灯 if (uiPanel43 != null && !uiPanel43.IsDisposed) uiPanel43.Visible = isHighTempMode; // 水箱加热按钮 if (uiButton4 != null && !uiButton4.IsDisposed) uiButton4.Visible = isHighTempMode; // 出口温度判定设置 if (uiLabel48 != null && !uiLabel48.IsDisposed) uiLabel48.Visible = isHighTempMode; if (uiTextBox9 != null && !uiTextBox9.IsDisposed) uiTextBox9.Visible = isHighTempMode; // 箱体温度设置 if (uiLabel37 != null && !uiLabel37.IsDisposed) uiLabel37.Visible = isHighTempMode; if (uiTextBox4 != null && !uiTextBox4.IsDisposed) uiTextBox4.Visible = isHighTempMode; // ========== 常温模式专属控件(常温模式显示,高温模式隐藏) ========== // 常温实时液位(mm) if (uiPanel23 != null && !uiPanel23.IsDisposed) uiPanel23.Visible = !isHighTempMode; // 常温加水按钮 if (uiButton13 != null && !uiButton13.IsDisposed) uiButton13.Visible = !isHighTempMode; // 常温加水指示灯 if (uiPanel38 != null && !uiPanel38.IsDisposed) uiPanel38.Visible = !isHighTempMode; // 写入按钮始终显示 if (uiButton8 != null && !uiButton8.IsDisposed) uiButton8.Visible = true; // 恢复布局更新,一次性重绘所有变更 this.ResumeLayout(true); Debug.WriteLine($"[UpdateControlsVisibilityByMode] 模式切换完成 - 高温模式: {isHighTempMode}"); } catch (ObjectDisposedException ex) { Debug.WriteLine($"[UpdateControlsVisibilityByMode] 控件已释放: {ex.Message}"); // 确保恢复布局 try { this.ResumeLayout(true); } catch { } } catch (Exception ex) { Debug.WriteLine($"[UpdateControlsVisibilityByMode] 更新控件可见性失败: {ex.Message}"); // 确保恢复布局 try { this.ResumeLayout(true); } catch { } } } //温度保护 private void uiTextBox12_Click(object sender, EventArgs e) { SafeInvoke(() => { ma?.WriteToPLCForNew(uiTextBox12.Text.Trim(), 3484, Function.DataType.浮点型); }); } //压力保护 private void uiTextBox13_Click(object sender, EventArgs e) { SafeInvoke(() => { ma?.WriteToPLCForNew(uiTextBox13.Text.Trim(), 3134, Function.DataType.浮点型); }); } private void uiTextBox14_Click(object sender, EventArgs e) { SafeInvoke(() => { ma?.WriteToPLCForNew(uiTextBox14.Text.Trim(), 2406, Function.DataType.整形, isok: true); }); } } }