using Google.Protobuf.WellKnownTypes; using JinYuan.ControlLib; using JinYuan.Helper; using JinYuan.MES.Models; using JinYuan.Models; using JinYuan.Models.HelperAttribute; using JinYuan.VirtualDataLibrary; using Language; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Documents; using System.Windows.Forms; namespace LargeSquareOne { public partial class FrmBatteryStatus : MultiLanguageForm { #region 字段定义 // 电池控件字典:Key=stationNo(1/2/3),Value=控件字典(Key=layer-row-col) private readonly Dictionary> _batteryControlsByStationNo = new Dictionary>(); // 条码到控件映射(加速查找) private readonly Dictionary _barcodeToControlMap = new Dictionary(); // 数据绑定列表 private readonly BindingList _replaceRecords = new BindingList(); private readonly BindingList _ngBatteryRecords = new BindingList(); private readonly BindingList _allBatteryRecords = new BindingList(); // 统计标签字典 private readonly Dictionary> _statisticsLabelsByLoc = new Dictionary>(); // 并发控制 private readonly SemaphoreSlim _operationSemaphore = new SemaphoreSlim(1, 1); private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); // 防抖控制 private DateTime _lastStatisticsUpdateTime = DateTime.MinValue; private DateTime _lastBatteryClickTime = DateTime.MinValue; // 状态标记 private bool _isControlsInitialized = false; // 统计项显示名称 private readonly string[] _statusDisplayNames = new string[] { "电芯替换总数", // GradeNG "电芯装箱NG总数", // PackNG "电芯档位&装箱OK总数", // Normal "满箱还缺总数" // Init }; // 性能监控 private PerformanceCounter _cpuUsageCounter; #endregion #region 构造函数 public FrmBatteryStatus() { InitializeComponent(); // 基础窗体设置 ConfigureFormProperties(); // 性能优化设置 ApplyPerformanceOptimizations(); // 初始化控件 InitializeDataGridViews(); BindScannerEvents(); InitializeDataBindings(); // 事件绑定 Load += FrmBatteryStatus_Load; // 性能监控初始化 InitializePerformanceMonitoring(); } #endregion #region 初始化方法 /// /// 配置窗体基础属性 /// private void ConfigureFormProperties() { Dock = DockStyle.Fill; AutoSize = false; FormBorderStyle = FormBorderStyle.None; Padding = new Padding(0); Margin = new Padding(0); // 双缓冲设置 SetStyle( ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.ResizeRedraw, true); DoubleBuffered = true; SetStyle(ControlStyles.SupportsTransparentBackColor, false); } /// /// 应用全局性能优化 /// private void ApplyPerformanceOptimizations() { // 禁用不必要的动画 Application.EnableVisualStyles(); //Application.SetCompatibleTextRenderingDefault(false); // 递归设置所有控件双缓冲 SetDoubleBufferingRecursive(this, true); // 禁用自动滚动减少重绘 AutoScroll = false; AutoScrollMinSize = new Size(0, 0); // 优化TabControl if (tabBattery != null) { SetDoubleBuffering(tabBattery, true); } if (_cpuUsageCounter != null) { _cpuUsageCounter.Dispose(); _cpuUsageCounter = null; } } /// /// 初始化DataGridView控件 /// private void InitializeDataGridViews() { OptimizeDataGridView(dgv_ngRsn); OptimizeDataGridView(dgvReplaceBattery); } /// /// 绑定扫描枪输入事件 /// private void BindScannerEvents() { // 回车切换焦点 txtBox_Barcode.KeyDown += (s, e) => { if (e.KeyCode == Keys.Enter && !string.IsNullOrEmpty(txtBox_Barcode.Text.Trim())) { e.SuppressKeyPress = true; txtBox_SubBarcode?.Focus(); txtBox_SubBarcode?.SelectAll(); } }; // 焦点获取时全选文本 txtBox_Barcode.Enter += (s, e) => ((TextBox)s)?.SelectAll(); txtBox_SubBarcode.Enter += (s, e) => ((TextBox)s)?.SelectAll(); } /// /// 初始化数据绑定 /// private void InitializeDataBindings() { dgvReplaceBattery.DataSource = _replaceRecords; dgv_ngRsn.DataSource = _ngBatteryRecords; // 验证绑定 Debug.WriteLine($"dgv_ngRsn数据源类型:{dgv_ngRsn.DataSource?.GetType().Name}"); Debug.WriteLine($"dgv_ngRsn列数:{dgv_ngRsn.Columns.Count}"); _ngBatteryRecords.ListChanged += (s, e) => { if (dgv_ngRsn.IsHandleCreated) dgv_ngRsn.BeginInvoke(() => dgv_ngRsn.Invalidate()); }; _replaceRecords.ListChanged += (s, e) => { if (dgvReplaceBattery.IsHandleCreated) dgvReplaceBattery.BeginInvoke(() => dgvReplaceBattery.Invalidate()); }; } /// /// 初始化性能监控 /// private void InitializePerformanceMonitoring() { try { // 先释放旧的计数器 if (_cpuUsageCounter != null) { _cpuUsageCounter.Dispose(); _cpuUsageCounter = null; } _cpuUsageCounter = new PerformanceCounter( "Process", "% Processor Time", Process.GetCurrentProcess().ProcessName); } catch (Exception ex) { LogHelper.Instance.WriteError($"性能监控初始化失败:{ex}", "BatteryStatusLog"); _cpuUsageCounter = null; // 确保置空 } } #endregion #region 性能优化相关方法 /// /// 优化DataGridView性能 /// private void OptimizeDataGridView(DataGridView dgv) { if (dgv == null) return; // 设置双缓冲 var doubleBufferProp = dgv.GetType().GetProperty( "DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); doubleBufferProp?.SetValue(dgv, true); dgv.EnableHeadersVisualStyles = false; dgv.AutoGenerateColumns = false; dgv.RowHeadersVisible = true; dgv.AllowUserToAddRows = false; dgv.AllowUserToDeleteRows = false; dgv.AllowUserToOrderColumns = false; dgv.AllowUserToResizeRows = false; dgv.ReadOnly = true; dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect; dgv.MultiSelect = false; // 减少绘制开销 dgv.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing; dgv.ColumnHeadersHeight = 25; dgv.RowTemplate.Height = 22; dgv.ScrollBars = ScrollBars.Vertical; } /// /// 设置控件双缓冲 /// /// 目标控件 /// 是否启用 private void SetDoubleBuffering(Control control, bool enable) { if (control == null) return; try { var prop = control.GetType().GetProperty( "DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic); prop?.SetValue(control, enable); } catch (Exception ex) { LogHelper.Instance.WriteLog($"设置双缓冲失败:{ex.Message}", "BatteryStatusLog"); } } /// /// 递归设置控件双缓冲 /// private void SetDoubleBufferingRecursive(Control control, bool enable) { if (control == null) return; try { SetDoubleBuffering(control, enable); foreach (Control child in control.Controls) { SetDoubleBufferingRecursive(child, enable); } } catch { // 忽略设置失败 } } #endregion #region 窗体加载与控件初始化 private async void FrmBatteryStatus_Load(object sender, EventArgs e) { try { if (_isControlsInitialized) return; SafeUI(() => { this.SuspendLayout(); SetPanelsVisibility(false); }); await Task.Delay(100); // 所有控件创建必须走 UI() SafeUI(() => { InitializeBatteryControls(); _isControlsInitialized = true; panelExt_Grade1?.Invalidate(); panelExt_Grade2?.Invalidate(); panelExt_Grade3?.Invalidate(); tabBattery?.Invalidate(); this.ResumeLayout(false); Invalidate(); SetPanelsVisibility(true); }); } catch (Exception ex) { LogHelper.Instance.WriteError($"加载电池界面异常:{ex}", "BatteryStatusLog"); } } /// /// 异步初始化电池控件(避免UI阻塞) /// private async Task InitializeBatteryControlsAsync() { await Task.Run(() => { if (InvokeRequired) { Invoke(new Action(InitializeBatteryControls)); } else { InitializeBatteryControls(); } }).ConfigureAwait(false); } /// /// 初始化电池控件 /// private void InitializeBatteryControls() { try { // 获取配置参数 var config = CommonMethods.mesConfig; int layers = config?.packLayers ?? 4; int rows = config?.rowsPerLayer ?? 5; int cols = config?.colsPerLayer ?? 12; Debug.WriteLine($"初始化电池控件:层={layers}, 行={rows}, 列={cols}"); // 暂停面板布局更新 SuspendPanelsLayout(); ClearPanelsControls(); // 获取FD配置 var fdConfig = CommonMethods.curFdConfig; if (fdConfig == null) return; // 初始化各档位控件 InitializeGradeControls(1, fdConfig.Grade1, panelExt_Grade1, layers, rows, cols); InitializeGradeControls(2, fdConfig.Grade2, panelExt_Grade2, layers, rows, cols); InitializeGradeControls(3, fdConfig.Grade3, panelExt_Grade3, layers, rows, cols); // 恢复布局 ResumePanelsLayout(); // 统计控件数量 int totalControls = _batteryControlsByStationNo.Values.Sum(d => d.Count); Debug.WriteLine($"电池控件初始化完成,总控件数:{totalControls}"); } catch (Exception ex) { Debug.WriteLine($"控件初始化异常:{ex.Message}"); LogHelper.Instance.WriteError($"初始化电池控件异常:{ex}", "BatteryStatusLog"); } } // 窗体关闭时释放资源 protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); //// 取消异步任务 //_cancellationTokenSource.Cancel(); _cancellationTokenSource.Token.UnregisterAll(); // 新增:移除所有注册的回调 // 安全取消 try { _cancellationTokenSource.Cancel(true); // true=允许回调抛异常但不终止程序 } catch (AggregateException ex) { // 记录回调中的具体异常(关键:定位哪个回调出问题) foreach (var innerEx in ex.InnerExceptions) { LogHelper.Instance.WriteError($"取消任务时回调异常:{innerEx}", "BatteryStatusLog"); } } catch (Exception ex) { LogHelper.Instance.WriteError($"取消CancellationTokenSource异常:{ex}", "BatteryStatusLog"); } Task.Delay(100).Wait(); // 释放资源 _operationSemaphore.Dispose(); if (_cpuUsageCounter != null) { _cpuUsageCounter.Dispose(); _cpuUsageCounter = null; } lock (_batteryControlsByStationNo) { DisposeBatteryControls(); ClearAllPanels(); _batteryControlsByStationNo.Clear(); _statisticsLabelsByLoc.Clear(); _barcodeToControlMap.Clear(); } _cancellationTokenSource.Dispose(); } // 重写窗体显示方法,优化渲染 protected override void OnShown(EventArgs e) { base.OnShown(e); // 恢复布局 foreach (Control control in this.Controls) { control.ResumeLayout(false); } } /// /// 重写CreateParams减少闪烁 /// protected override CreateParams CreateParams { get { CreateParams cp = base.CreateParams; cp.ExStyle |= 0x02000000; // WS_EX_COMPOSITED return cp; } } #endregion #region 电池控件管理 /// /// 初始化指定档位的电池控件 /// /// 机架号(1/2/3) /// 档位名称 /// 容器面板 /// 层数 /// 行数 /// 列数 private void InitializeGradeControls(int stationNo, string grade, PanelExt container, int layers, int rows, int cols) { if (stationNo < 1 || stationNo > 3 || container == null || container.HasChildren) { Debug.WriteLine($"机架号{stationNo}错误或容器非空,跳过初始化"); return; } if (string.IsNullOrEmpty(grade) || grade == "不设置" || grade == "NG" ) { // 设置标签页文本 SetTabPageText(stationNo, grade); return; } try { // 设置标签页文本 SetTabPageText(stationNo, grade); // 初始化容器面板 container.Controls.Clear(); //container.AutoScroll = true; container.BackColor = Color.FromArgb(11, 20, 36); container.SuspendLayout(); container.Visible = false; container.Dock = DockStyle.Fill; container.Padding = new Padding(0); // 增加容器内边距 // 创建层级面板 var layerPanel = CreateLayerPanel(stationNo, grade, layers, rows, cols); // 创建统计区域 var statsGroup = CreateStatisticsGroupBox(stationNo, grade, out var statLabels); _statisticsLabelsByLoc[stationNo] = statLabels; statsGroup.Size = new Size(layerPanel.Width, 70); statsGroup.Location = new System.Drawing.Point(0, layerPanel.Bottom + 5); //statsGroup.Dock = DockStyle.Bottom; // 添加控件到容器 container.Controls.Add(layerPanel); container.Controls.Add(statsGroup); //container.AutoScrollMinSize = new Size(layerPanel.Width, statsGroup.Bottom); //container.ClientSize = new Size(layerPanel.Width + 10, statsGroup.Bottom + 10); // 恢复布局 container.ResumeLayout(true); container.Visible = true; container.Invalidate(); Debug.WriteLine($"机架号{stationNo}控件创建完成,总数:{layers * rows * cols}"); } catch (Exception ex) { Debug.WriteLine($"初始化机架号{stationNo}异常:{ex.Message}"); LogHelper.Instance.WriteError($"初始化机架号{stationNo}电池控件异常:{ex}", "BatteryStatusLog"); } } /// /// 创建层级面板 /// //创建分层的表格 private TableLayoutPanel CreateLayerPanel(int stationNo, string grade, int layers, int rows, int cols) { // 布局参数 int batterySize = 24; int cellPadding = 2; int cellSize = batterySize + cellPadding * 2; int rowNumColWidth = 40; // 行号列宽度 int layerColWidth = 40; // 层数列宽度 int totalColWidth = rowNumColWidth + (cellSize * cols); // 电池区域总列宽 int totalPanelWidth = layerColWidth + totalColWidth + 10; // 整体总宽度(+10px余量) int rowHeight = cellSize + cellPadding; // 每行高度 = 单元格高度 int layerHeight = (rowHeight * rows) + 2; // 每层高度 = 表头 + 电池行 int layerTotalHeight = rowHeight * rows + 6; // 每层总高度(+8px余量,确保最后一行显示) //外层TableLayoutPanel:分层(包含表头+所有层) TableLayoutPanel layerPanel = new TableLayoutPanel { RowCount = layers + 1, ColumnCount = 2, //Dock = DockStyle.Fill, // 顶部对齐,避免Fill压缩宽度 BackColor = Color.Transparent, CellBorderStyle = TableLayoutPanelCellBorderStyle.Single, //TableLayoutPanelCellBorderStyle.None, Margin = new Padding(0), AutoSizeMode = AutoSizeMode.GrowAndShrink, Size = new Size(totalPanelWidth, layerTotalHeight * layers + 35), //Margin = new Padding(0, 0, 0, 10), }; layerPanel.ColumnStyles.Clear(); layerPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, layerColWidth)); layerPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, totalColWidth)); // 设置行样式 layerPanel.RowStyles.Clear(); layerPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 25F)); //第一行 显示列号 for (int i = 1; i <= layers; i++) { layerPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, layerTotalHeight)); } // ========== 创建表头行 ========== // 表头-第一列(文本:层数/列) System.Windows.Forms.Label lblHeaderLayer = new System.Windows.Forms.Label { Text = "层", TextAlign = ContentAlignment.MiddleCenter, ForeColor = Color.White, Dock = DockStyle.Fill, Font = new Font("Microsoft YaHei", 9, FontStyle.Bold) }; layerPanel.Controls.Add(lblHeaderLayer, 0, 0); // 表头-第二列(列号容器) TableLayoutPanel tblColHeader = new TableLayoutPanel { RowCount = 1, ColumnCount = cols + 1, // 行号列 + 所有电池列 Dock = DockStyle.Fill, Size = new Size(totalColWidth, 25), //AutoSize = true, //AutoSizeMode = AutoSizeMode.GrowAndShrink, //BackColor = Color.Transparent, BackColor = Color.FromArgb(18, 30, 50), Margin = new Padding(0), CellBorderStyle = TableLayoutPanelCellBorderStyle.None }; tblColHeader.ColumnStyles.Clear(); tblColHeader.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, rowNumColWidth)); for (int col = 1; col <= cols; col++) { tblColHeader.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, cellSize)); } System.Windows.Forms.Label lblheaderCol = new System.Windows.Forms.Label { Text = "行/列", TextAlign = ContentAlignment.MiddleCenter, ForeColor = Color.White, Dock = DockStyle.Fill, Margin = new Padding(0), Font = new Font("Microsoft YaHei", 9, FontStyle.Bold), BackColor = Color.FromArgb(18, 30, 50), }; tblColHeader.Controls.Add(lblheaderCol, 0, 0); for (int col = 1; col <= cols; col++) { System.Windows.Forms.Label lblCol = new System.Windows.Forms.Label { Text = col.ToString(), TextAlign = ContentAlignment.MiddleCenter, ForeColor = Color.White, Dock = DockStyle.Fill, Margin = new Padding(0), Font = new Font("Microsoft YaHei", 9, FontStyle.Bold) }; tblColHeader.Controls.Add(lblCol, col, 0); } layerPanel.Controls.Add(tblColHeader, 1, 0); //CreateBatteryControls(stationNo, grade, layerPanel, layers, rows, cols); // 初始化控件字典 if (!_batteryControlsByStationNo.ContainsKey(stationNo)) { _batteryControlsByStationNo[stationNo] = new Dictionary(); } // ========== 遍历每层,创建电池控件 ========== for (int layer = 1; layer <= layers; layer++) { // 层数标签(第一列) System.Windows.Forms.Label lblLayer = new System.Windows.Forms.Label { Text = $"第{layer}层", TextAlign = ContentAlignment.MiddleCenter, ForeColor = Color.White, Dock = DockStyle.Fill, BackColor = Color.FromArgb(18, 30, 50), Font = new Font("Microsoft YaHei", 9, FontStyle.Bold), Margin = new Padding(0), Padding = new Padding(0) }; layerPanel.Controls.Add(lblLayer, 0, layer); System.Windows.Forms.Panel pnlBatteryContainer = new System.Windows.Forms.Panel { //Dock = DockStyle.Fill, //BackColor = Color.FromArgb(18, 30, 50), //BorderStyle = BorderStyle.FixedSingle, // 层边框 //Margin = new Padding(2), // 层之间的间距 //Padding = new Padding(3) Size = new Size(totalColWidth, layerTotalHeight), // 固定尺寸,和层高度一致 BackColor = Color.FromArgb(18, 30, 50), //BorderStyle = BorderStyle.FixedSingle, // 层边框 Margin = new Padding(3), // 层之间间距(统一) Padding = new Padding(1) }; // 内层TableLayoutPanel:当前层的行和列 TableLayoutPanel tblBattery = new TableLayoutPanel { //RowCount = totalRows, //ColumnCount = totalCols + 1, //Dock = DockStyle.Fill, // 填充容器 //AutoSize = true, //AutoSizeMode = AutoSizeMode.GrowAndShrink, //BackColor = Color.Transparent, //CellBorderStyle = TableLayoutPanelCellBorderStyle.None, //Margin = new Padding(0), //Padding = new Padding(5) RowCount = rows, ColumnCount = cols + 1, Size = new Size(totalColWidth, layerTotalHeight - 2), //Dock = DockStyle.Fill, BackColor = Color.Transparent, CellBorderStyle = TableLayoutPanelCellBorderStyle.None, Margin = new Padding(0), Padding = new Padding(0) }; tblBattery.RowStyles.Clear(); for (int r = 0; r < rows; r++) { tblBattery.RowStyles.Add(new RowStyle(SizeType.Absolute, rowHeight)); } tblBattery.ColumnStyles.Clear(); tblBattery.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, rowNumColWidth)); for (int c = 1; c <= cols; c++) { tblBattery.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, cellSize)); } // 遍历当前层的所有行和列,生成电池控件 for (int row = 1; row <= rows; row++) { System.Windows.Forms.Label lblrow = new System.Windows.Forms.Label { Text = row.ToString(), TextAlign = ContentAlignment.MiddleCenter, ForeColor = Color.White, Dock = DockStyle.Fill, Margin = new Padding(0), Font = new Font("Microsoft YaHei", 9, FontStyle.Bold) }; tblBattery.Controls.Add(lblrow, 0, row - 1); } for (int row = 1; row <= rows; row++) { for (int col = 1; col <= cols; col++) { BatteryControl battery = new BatteryControl(grade, layer, row, col, "") { Name = $"BatteryControl_{stationNo}_{location}", Size = new Size(batterySize, batterySize), Margin = new Padding(cellPadding), Anchor = AnchorStyles.None, //Dock = DockStyle.None, Dock = DockStyle.None, Tag = $"{stationNo}-{location}", Style = SeeSharpTools.JY.GUI.LED.LedStyle.Circular }; // 绑定点击事件 battery.OnBatteryClicked += OnBatteryControlClicked; // 添加到行列表格 tblBattery.Controls.Add(battery, col, row - 1); // 加入全局管理字典 string controlKey = $"{layer}-{row}-{col}"; _batteryControlsByStationNo[stationNo][controlKey] = battery; } } pnlBatteryContainer.Controls.Add(tblBattery); layerPanel.Controls.Add(pnlBatteryContainer, 1, layer); } return layerPanel; } //创建一个整体的表格 //private TableLayoutPanel CreateLayerPanel(int stationNo, string grade, int layers, int rows, int cols) //{ // // 布局参数 // int batterySize = 24; // int cellPadding = 2; // int cellSize = batterySize + cellPadding * 2; // int layerNumWidth = 50; // int totalPanelWidth = layerNumWidth * 2 + (cellSize * cols) + 18; // int totalPanelHeight = cellSize * rows * layers + 50; // 每层总高度(+8px余量,确保最后一行显示) // // 创建外层面板 // var layerPanel = new TableLayoutPanel // { // RowCount = layers * rows + 1, // ColumnCount = cols + 2, // BackColor = Color.Transparent, // CellBorderStyle = TableLayoutPanelCellBorderStyle.Single, // Margin = new Padding(0), // Size = new Size(totalPanelWidth, totalPanelHeight), // Padding = new Padding(0) // }; // // 设置列样式 // layerPanel.ColumnStyles.Clear(); // for (int i = 0; i < layerPanel.ColumnCount; i++) // { // if (i < 2) // layerPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, layerNumWidth)); // else // layerPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, cellSize)); // } // // 设置行样式 // layerPanel.RowStyles.Clear(); // for (int i = 0; i < layerPanel.RowCount; i++) // { // layerPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, cellSize)); // } // // 添加表头 // //AddPanelHeaders(layerPanel, cols, layerNumWidth, cellSize); // // 层数标签 // var layerHeader = new Label // { // Text = "层", // TextAlign = ContentAlignment.MiddleCenter, // ForeColor = Color.White, // BackColor = Color.FromArgb(18, 30, 50), // Dock = DockStyle.Fill, // Font = new Font("Microsoft YaHei", 9, FontStyle.Bold) // }; // layerPanel.Controls.Add(layerHeader, 0, 0); // // 行/列表头 // var rowColHeader = new Label // { // Text = "行/列", // TextAlign = ContentAlignment.MiddleCenter, // ForeColor = Color.White, // Dock = DockStyle.Fill, // Margin = new Padding(0), // Font = new Font("Microsoft YaHei", 9, FontStyle.Bold), // BackColor = Color.FromArgb(18, 30, 50) // }; // layerPanel.Controls.Add(rowColHeader, 1, 0); // // 列号标签 // for (int col = 1; col <= cols; col++) // { // var colLabel = new Label // { // Text = col.ToString(), // TextAlign = ContentAlignment.MiddleCenter, // ForeColor = Color.White, // Dock = DockStyle.Fill, // Margin = new Padding(0), // Padding = new Padding(0), // Font = new Font("Microsoft YaHei", 9, FontStyle.Bold), // BackColor = Color.FromArgb(18, 30, 50) // }; // layerPanel.Controls.Add(colLabel, col + 1, 0); // } // // 创建电池控件 // //CreateBatteryControls(stationNo, grade, layerPanel, layers, rows, cols); // // 初始化控件字典 // if (!_batteryControlsByStationNo.ContainsKey(stationNo)) // { // _batteryControlsByStationNo[stationNo] = new Dictionary(); // } // for (int layer = 0; layer < layers; layer++) // { // // 添加层数标签 // var layerLabel = new Label // { // Text = $"第{layer + 1}层", // TextAlign = ContentAlignment.MiddleCenter, // ForeColor = Color.White, // Dock = DockStyle.Fill, // BackColor = Color.FromArgb(18, 30, 50), // Font = new Font("Microsoft YaHei", 9, FontStyle.Bold), // Margin = new Padding(0) // }; // layerPanel.Controls.Add(layerLabel, 0, layer * rows + 1); // layerPanel.SetRowSpan(layerLabel, rows); // // 添加行号标签 // for (int row = 1; row <= rows; row++) // { // var rowLabel = new Label // { // Text = row.ToString(), // TextAlign = ContentAlignment.MiddleCenter, // ForeColor = Color.White, // Dock = DockStyle.Fill, // Margin = new Padding(0), // Font = new Font("Microsoft YaHei", 9, FontStyle.Bold), // BackColor = Color.FromArgb(18, 30, 50) // }; // layerPanel.Controls.Add(rowLabel, 1, layer * rows + row); // for (int col = 1; col <= cols; col++) // { // string location = $"{layer}-{row}-{col}"; // // 创建电池控件 // var batteryControl = new BatteryControl(grade, layer, row, col, "", JinYuan.ControlLib.BatteryStatus.Init) // { // Name = $"BatteryControl_{stationNo}_{location}", // Size = new Size(batterySize, batterySize), // Margin = new Padding(cellPadding), // Anchor = AnchorStyles.None, // //Dock = DockStyle.None, // Dock = DockStyle.Fill, // Tag = $"{stationNo}-{location}", // Style = SeeSharpTools.JY.GUI.LED.LedStyle.Circular // }; // // 绑定点击事件 // batteryControl.OnBatteryClicked += OnBatteryControlClicked; // // 添加到面板 // layerPanel.Controls.Add(batteryControl, col + 1, row + layer * rows); // // 加入管理字典 // string controlKey = $"{layer}-{row}-{col}"; // _batteryControlsByStationNo[stationNo][controlKey] = batteryControl; // } // } // // 创建具体电池控件 // //AddBatteryControlCells(stationNo, grade, layerPanel, layer, rows, cols, batterySize, cellPadding); // } // return layerPanel; //} /// /// 创建电池控件 /// private void CreateBatteryControls(int stationNo, string grade, TableLayoutPanel layerPanel, int layers, int rows, int cols) { // 初始化控件字典 if (!_batteryControlsByStationNo.ContainsKey(stationNo)) { _batteryControlsByStationNo[stationNo] = new Dictionary(); } int cellPadding = 1; int batterySize = 24; int cellSize = batterySize + cellPadding * 2; //int rowNumWidth = 40; for (int layer = 0; layer < layers; layer++) { // 添加层数标签 var layerLabel = new Label { Text = $"第{layer + 1}层", TextAlign = ContentAlignment.MiddleCenter, ForeColor = Color.White, Dock = DockStyle.Fill, BackColor = Color.FromArgb(18, 30, 50), Font = new Font("Microsoft YaHei", 9, FontStyle.Bold), Margin = new Padding(0) }; layerPanel.Controls.Add(layerLabel, 0, layer * rows + 1); layerPanel.SetRowSpan(layerLabel, rows); // 添加行号标签 AddRowNumberLabels(layerPanel, layer, rows); // 创建具体电池控件 AddBatteryControlCells(stationNo, grade, layerPanel, layer, rows, cols, batterySize, cellPadding); } } /// /// 添加电池控件单元格 /// private void AddBatteryControlCells(int stationNo, string grade, TableLayoutPanel layerPanel, int layer, int rows, int cols, int batterySize, int cellPadding) { for (int row = 1; row <= rows; row++) { for (int col = 1; col <= cols; col++) { string location = $"{layer}-{row}-{col}"; // 创建电池控件 var batteryControl = new BatteryControl(grade, layer, row, col, "", JinYuan.ControlLib.BatteryStatus.Init) { Name = $"BatteryControl_{stationNo}_{location}", Size = new Size(batterySize, batterySize), Margin = new Padding(cellPadding), Anchor = AnchorStyles.None, //Dock = DockStyle.None, Dock = DockStyle.Fill, Tag = $"{stationNo}-{location}", Style = SeeSharpTools.JY.GUI.LED.LedStyle.Circular }; // 绑定点击事件 batteryControl.OnBatteryClicked += OnBatteryControlClicked; // 添加到面板 layerPanel.Controls.Add(batteryControl, col+1, row + layer * rows); // 加入管理字典 string controlKey = $"{layer}-{row}-{col}"; _batteryControlsByStationNo[stationNo][controlKey] = batteryControl; } } } /// /// 创建统计信息GroupBox /// private GroupBoxEX CreateStatisticsGroupBox(int stationNo, string grade, out List