using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using APS7100TestTool.Services; namespace APS7100TestTool.Forms { public partial class RegisterViewerForm : Form { private ModbusTcpServerService _modbusService; private System.Windows.Forms.Timer _refreshTimer; // 存储自定义监视的地址 private List _customEntries = new List(); private class CustomRegisterEntry { public int Address { get; set; } public string DataType { get; set; } } public RegisterViewerForm() { InitializeComponent(); InitializeDataGridColumns(); } public RegisterViewerForm(ModbusTcpServerService modbusService) : this() { _modbusService = modbusService; InitializeTimer(); if (_modbusService != null) { LoadRegisterData(); } } private void InitializeDataGridColumns() { dgvRegisters.Columns.Clear(); dgvRegisters.Columns.Add(new DataGridViewTextBoxColumn { Name = "Source", HeaderText = "来源", Width = 80 }); dgvRegisters.Columns.Add(new DataGridViewTextBoxColumn { Name = "Address", HeaderText = "地址", Width = 80 }); dgvRegisters.Columns.Add(new DataGridViewTextBoxColumn { Name = "DataType", HeaderText = "类型", Width = 80 }); dgvRegisters.Columns.Add(new DataGridViewTextBoxColumn { Name = "Value", HeaderText = "当前值", Width = 120, DefaultCellStyle = new DataGridViewCellStyle { Alignment = DataGridViewContentAlignment.MiddleRight, Font = new Font("Consolas", 10F, FontStyle.Bold), ForeColor = Color.FromArgb(0, 100, 180) } }); dgvRegisters.Columns.Add(new DataGridViewTextBoxColumn { Name = "Description", HeaderText = "描述", Width = 300 }); // 设置默认选中项 if (cmbDataType.Items.Count > 0) { cmbDataType.SelectedIndex = 0; } } private void InitializeTimer() { if (DesignMode) return; _refreshTimer = new System.Windows.Forms.Timer(); _refreshTimer.Interval = (int)numRefreshInterval.Value; _refreshTimer.Tick += RefreshTimer_Tick; if (chkAutoRefresh.Checked) { _refreshTimer.Start(); } } private void LoadRegisterData() { if (_modbusService == null || !_modbusService.IsRunning) { lblStatus.Text = "状态: Modbus 服务未运行"; lblStatus.ForeColor = Color.Red; return; } try { dgvRegisters.Rows.Clear(); var registerData = _modbusService.ReadAllConfiguredRegisters(); var mappings = _modbusService.GetMappings(); // 添加配置中的寄存器 foreach (var map in mappings) { string value = "N/A"; if (registerData.TryGetValue(map.Address, out var data)) { value = data.RawValue; } int rowIndex = dgvRegisters.Rows.Add( "配置", map.Address.ToString(), map.DataType ?? "Int16", value, map.Description ?? "" ); if (map.OperationType == "Read") { dgvRegisters.Rows[rowIndex].DefaultCellStyle.BackColor = Color.FromArgb(230, 255, 230); } } // 添加自定义监视的寄存器 foreach (var entry in _customEntries) { string value = ReadRegisterValue(entry.Address, entry.DataType); int rowIndex = dgvRegisters.Rows.Add( "自定义", entry.Address.ToString(), entry.DataType, value, "(自定义监视)" ); dgvRegisters.Rows[rowIndex].DefaultCellStyle.BackColor = Color.FromArgb(230, 240, 255); } int totalCount = mappings.Count + _customEntries.Count; lblStatus.Text = $"状态: 配置 {mappings.Count} + 自定义 {_customEntries.Count} = 共 {totalCount} 个 | 最后刷新: {DateTime.Now:HH:mm:ss}"; lblStatus.ForeColor = Color.Green; } catch (Exception ex) { lblStatus.Text = $"状态: 读取失败 - {ex.Message}"; lblStatus.ForeColor = Color.Red; } } private string ReadRegisterValue(int address, string dataType) { try { if (dataType == "Float") { var value = _modbusService.ReadHoldingFloat((ushort)address); return value.HasValue ? value.Value.ToString("F4") : "N/A"; } else { var value = _modbusService.ReadHoldingRegister((ushort)address); if (!value.HasValue) return "N/A"; if (dataType == "Int16") return ((short)value.Value).ToString(); else return value.Value.ToString(); } } catch { return "读取失败"; } } private void RefreshTimer_Tick(object sender, EventArgs e) { RefreshValues(); } private void RefreshValues() { if (_modbusService == null || !_modbusService.IsRunning) { lblStatus.Text = "状态: Modbus 服务未运行"; lblStatus.ForeColor = Color.Red; return; } try { var registerData = _modbusService.ReadAllConfiguredRegisters(); foreach (DataGridViewRow row in dgvRegisters.Rows) { if (row.Cells["Address"].Value == null) continue; if (int.TryParse(row.Cells["Address"].Value.ToString(), out int address)) { string oldValue = row.Cells["Value"].Value?.ToString() ?? ""; string newValue = ""; string source = row.Cells["Source"].Value?.ToString() ?? ""; string dataType = row.Cells["DataType"].Value?.ToString() ?? "UInt16"; if (source == "配置") { if (registerData.TryGetValue(address, out var data)) { newValue = data.RawValue; } } else { newValue = ReadRegisterValue(address, dataType); } row.Cells["Value"].Value = newValue; if (oldValue != newValue && !string.IsNullOrEmpty(oldValue)) { row.Cells["Value"].Style.BackColor = Color.Yellow; } else { row.Cells["Value"].Style.BackColor = Color.Empty; } } } int configCount = _modbusService.GetMappings().Count; lblStatus.Text = $"状态: 配置 {configCount} + 自定义 {_customEntries.Count} | 最后刷新: {DateTime.Now:HH:mm:ss}"; lblStatus.ForeColor = Color.Green; } catch (Exception ex) { lblStatus.Text = $"状态: 刷新失败 - {ex.Message}"; lblStatus.ForeColor = Color.Red; } } private void ChkAutoRefresh_CheckedChanged(object sender, EventArgs e) { if (_refreshTimer == null) return; if (chkAutoRefresh.Checked) { _refreshTimer.Start(); } else { _refreshTimer.Stop(); } } private void NumRefreshInterval_ValueChanged(object sender, EventArgs e) { if (_refreshTimer != null) { _refreshTimer.Interval = (int)numRefreshInterval.Value; } } private void BtnRefresh_Click(object sender, EventArgs e) { LoadRegisterData(); } private void BtnClose_Click(object sender, EventArgs e) { this.Close(); } private void BtnAddCustom_Click(object sender, EventArgs e) { int startAddr = (int)numStartAddr.Value; int count = (int)numCount.Value; string dataType = cmbDataType.SelectedItem?.ToString() ?? "UInt16"; int added = 0; for (int i = 0; i < count; i++) { int addr = startAddr + i; if (dataType == "Float" && i > 0) { addr = startAddr + (i * 2); } bool exists = _customEntries.Exists(e => e.Address == addr); if (!exists) { _customEntries.Add(new CustomRegisterEntry { Address = addr, DataType = dataType }); added++; } } if (added > 0) { LoadRegisterData(); MessageBox.Show($"已添加 {added} 个自定义监视地址", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("所选地址已存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void BtnClearCustom_Click(object sender, EventArgs e) { if (_customEntries.Count == 0) { MessageBox.Show("没有自定义监视的地址", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } var result = MessageBox.Show($"确定要清除所有 {_customEntries.Count} 个自定义监视地址吗?", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.Yes) { _customEntries.Clear(); LoadRegisterData(); } } private void RegisterViewerForm_FormClosing(object sender, FormClosingEventArgs e) { _refreshTimer?.Stop(); _refreshTimer?.Dispose(); } } }