基线:全量源码首提(D1 版本控制落地,含第一轮优化 B1-B4/A1/A4/缩放修复)
This commit is contained in:
@@ -0,0 +1,783 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using Smart.CustomComponents;
|
||||
|
||||
namespace 成套报价软件
|
||||
{
|
||||
/// <summary>
|
||||
/// 垂直母排载流量核算 (GCS 计算壳体) —— 交互逻辑。
|
||||
/// 从独立项目 GCS铜排壳体计算 集成进成套报价软件,由母排页"垂直母排计算"按钮弹出。
|
||||
/// UI 布局定义见 GCS母排计算窗口.ui.cs。
|
||||
/// </summary>
|
||||
public partial class GCS母排计算窗口
|
||||
{
|
||||
// ============================================================
|
||||
// 常量:列/行/铜排/抽屉型号
|
||||
// ============================================================
|
||||
|
||||
private const int ColumnCount = 11;
|
||||
private const int CircuitRows = 18;
|
||||
private const int SummaryRows = 5;
|
||||
|
||||
private static readonly double[] SummaryFactors = { 1.0, 0.9, 0.8, 0.7, 0.6 };
|
||||
private static readonly string[] SummaryLabels = { "SUM", "SUM×0.9", "SUM×0.8", "SUM×0.7", "SUM×0.6" };
|
||||
private static readonly string[] ColumnHeaders =
|
||||
{ "1#", "2#", "3#", "4#", "5#", "6#", "7#", "8#", "9#", "10#", "n#" };
|
||||
|
||||
private static readonly string[] BusbarSpecs =
|
||||
{ "TMY-30×6", "TMY-40×6", "TMY-50×6", "TMY-60×6", "TMY-80×6", "TMY-100×6", "TMY-120×6" };
|
||||
private static readonly double[] BusbarRatings =
|
||||
{ 540, 710, 840, 990, 1302, 1593, 1877 };
|
||||
|
||||
private static readonly string[] QuoteItems =
|
||||
{ "柜体", "抽屉 1/2", "抽屉 125", "抽屉 250", "抽屉 400", "抽屉 630", "抽屉 800" };
|
||||
private static readonly double[] DefaultDrawerPrices = { 450, 400, 500, 600, 700, 1000 };
|
||||
|
||||
private const double DefaultCabinetPrice = 2100;
|
||||
private const double DefaultCabinetQty = 1;
|
||||
|
||||
private static readonly Color InputCellBackColor = Color.FromArgb(204, 255, 204);
|
||||
private static readonly Color SummaryRowBackColor = Color.FromArgb(255, 255, 204);
|
||||
private static readonly Color SumRowBackColor = Color.FromArgb(255, 242, 204);
|
||||
private static readonly Color RecommendBackColor = Color.FromArgb(146, 208, 80);
|
||||
|
||||
private const int QCOL_ITEM = 0;
|
||||
private const int QCOL_PRICE = 1;
|
||||
private const int QCOL_QTY = 2;
|
||||
private const int QCOL_SUB = 3;
|
||||
|
||||
private bool _isCalculating;
|
||||
private double _maxLoadCurrent;
|
||||
|
||||
/// <summary>推荐铜排窗口引用(非模态打开,防重复弹出)。</summary>
|
||||
private GCS推荐铜排窗口 _recommendForm;
|
||||
|
||||
public GCS母排计算窗口()
|
||||
{
|
||||
InitializeComponent();
|
||||
SetupRecommendLabel();
|
||||
BuildCurrentsGrid();
|
||||
BuildBusbarGrid();
|
||||
BuildQuoteGrid();
|
||||
InitDefaultValues();
|
||||
InitComboBox();
|
||||
WireEvents();
|
||||
RecalculateAll();
|
||||
this.Load += (s, e) => FitRecommendText();
|
||||
}
|
||||
|
||||
private void SetupRecommendLabel()
|
||||
{
|
||||
lblRecommend.Anchor = AnchorStyles.Top | AnchorStyles.Left;
|
||||
lblRecommend.AutoSize = false;
|
||||
lblRecommend.AutoEllipsis = false;
|
||||
lblRecommend.TextAlign = ContentAlignment.MiddleLeft;
|
||||
// 保持设计器布局(在 panel1 内,Location(0,4),Size(253,29)),不要覆盖位置/尺寸
|
||||
grpBusbar.SizeChanged += (s, e) => FitRecommendText();
|
||||
}
|
||||
|
||||
private void FitRecommendText()
|
||||
{
|
||||
if (lblRecommend == null) return;
|
||||
string text = lblRecommend.Text;
|
||||
if (string.IsNullOrEmpty(text)) return;
|
||||
|
||||
// 固定使用设计器设置的宽度(253),不修改位置/尺寸,避免覆盖右侧"插入铜排/查看抽屉推荐铜排"按钮。
|
||||
int fixedWidth = lblRecommend.Width;
|
||||
if (fixedWidth <= 0) fixedWidth = 253;
|
||||
|
||||
// 从大到小试字号,找单行能在固定宽度内放下的最大字号
|
||||
float[] fontSizes = { 11F, 10F, 9F, 8F };
|
||||
Font chosenFont = null;
|
||||
foreach (float fs in fontSizes)
|
||||
{
|
||||
var f = new Font("宋体", fs);
|
||||
var size = TextRenderer.MeasureText(text, f,
|
||||
new Size(int.MaxValue, int.MaxValue),
|
||||
TextFormatFlags.NoPadding);
|
||||
if (size.Width <= fixedWidth)
|
||||
{
|
||||
chosenFont = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (chosenFont != null)
|
||||
{
|
||||
lblRecommend.Font = chosenFont;
|
||||
}
|
||||
else
|
||||
{
|
||||
lblRecommend.Font = new Font("宋体", 8F);
|
||||
}
|
||||
lblRecommend.Invalidate();
|
||||
}
|
||||
|
||||
private void InitComboBox()
|
||||
{
|
||||
comboBox1.Items.Clear();
|
||||
comboBox1.Items.Add("全部");
|
||||
for (int c = 0; c < ColumnCount; c++)
|
||||
{
|
||||
comboBox1.Items.Add(ColumnHeaders[c]);
|
||||
}
|
||||
comboBox1.SelectedIndex = 1; // ★默认"1#"(原始行为,2026-09-26 曾被擅改为"全部"已恢复)
|
||||
}
|
||||
|
||||
private void BuildCurrentsGrid()
|
||||
{
|
||||
gridCurrents.SuspendLayout();
|
||||
gridCurrents.Columns.Clear();
|
||||
gridCurrents.Rows.Clear();
|
||||
|
||||
for (int c = 0; c < ColumnCount; c++)
|
||||
{
|
||||
var col = new DataGridViewTextBoxColumn
|
||||
{
|
||||
Name = "col_" + c,
|
||||
HeaderText = ColumnHeaders[c],
|
||||
Width = 80,
|
||||
SortMode = DataGridViewColumnSortMode.NotSortable
|
||||
};
|
||||
gridCurrents.Columns.Add(col);
|
||||
}
|
||||
|
||||
for (int r = 0; r < CircuitRows; r++)
|
||||
{
|
||||
int idx = gridCurrents.Rows.Add();
|
||||
gridCurrents.Rows[idx].HeaderCell.Value = "第" + (r + 1) + "路(A)";
|
||||
gridCurrents.Rows[idx].HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleLeft;
|
||||
}
|
||||
|
||||
for (int s = 0; s < SummaryRows; s++)
|
||||
{
|
||||
int idx = gridCurrents.Rows.Add();
|
||||
var row = gridCurrents.Rows[idx];
|
||||
row.HeaderCell.Value = SummaryLabels[s];
|
||||
row.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleLeft;
|
||||
row.HeaderCell.Style.Font = new Font("宋体", 9, FontStyle.Bold);
|
||||
row.ReadOnly = true;
|
||||
Color bg = s == 0 ? SumRowBackColor : SummaryRowBackColor;
|
||||
for (int c = 0; c < ColumnCount; c++)
|
||||
{
|
||||
row.Cells[c].Style.BackColor = bg;
|
||||
row.Cells[c].Style.Font = new Font("宋体", 9, FontStyle.Bold);
|
||||
row.Cells[c].Value = "";
|
||||
}
|
||||
}
|
||||
|
||||
for (int r = 0; r < CircuitRows; r++)
|
||||
{
|
||||
for (int c = 0; c < ColumnCount; c++)
|
||||
{
|
||||
gridCurrents.Rows[r].Cells[c].Style.BackColor = InputCellBackColor;
|
||||
}
|
||||
}
|
||||
|
||||
gridCurrents.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
|
||||
gridCurrents.ColumnHeadersHeight = 30;
|
||||
gridCurrents.RowHeadersWidth = 95;
|
||||
gridCurrents.AllowUserToResizeRows = false;
|
||||
DisableAdgvFilterButtons(gridCurrents);
|
||||
gridCurrents.ResumeLayout();
|
||||
}
|
||||
|
||||
private void BuildBusbarGrid()
|
||||
{
|
||||
gridBusbar.SuspendLayout();
|
||||
gridBusbar.Columns.Clear();
|
||||
gridBusbar.Rows.Clear();
|
||||
|
||||
var colSpec = new DataGridViewTextBoxColumn
|
||||
{
|
||||
Name = "bspec",
|
||||
HeaderText = "铜排规格",
|
||||
Width = 160,
|
||||
SortMode = DataGridViewColumnSortMode.NotSortable
|
||||
};
|
||||
var colRate = new DataGridViewTextBoxColumn
|
||||
{
|
||||
Name = "brate",
|
||||
HeaderText = "载流量 (A)",
|
||||
Width = 160,
|
||||
SortMode = DataGridViewColumnSortMode.NotSortable
|
||||
};
|
||||
gridBusbar.Columns.Add(colSpec);
|
||||
gridBusbar.Columns.Add(colRate);
|
||||
|
||||
for (int i = 0; i < BusbarSpecs.Length; i++)
|
||||
{
|
||||
int idx = gridBusbar.Rows.Add();
|
||||
gridBusbar.Rows[idx].Cells[0].Value = BusbarSpecs[i];
|
||||
gridBusbar.Rows[idx].Cells[1].Value = BusbarRatings[i].ToString("0") + "A";
|
||||
}
|
||||
|
||||
gridBusbar.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
|
||||
gridBusbar.ColumnHeadersHeight = 28;
|
||||
int totalW = gridBusbar.ClientSize.Width;
|
||||
if (totalW > 20)
|
||||
{
|
||||
gridBusbar.Columns[0].Width = totalW / 2;
|
||||
gridBusbar.Columns[1].Width = totalW - totalW / 2;
|
||||
}
|
||||
gridBusbar.ClearSelection();
|
||||
gridBusbar.ScrollBars = ScrollBars.Vertical;
|
||||
DisableAdgvFilterButtons(gridBusbar);
|
||||
gridBusbar.ResumeLayout();
|
||||
}
|
||||
|
||||
private void BuildQuoteGrid()
|
||||
{
|
||||
gridQuote.SuspendLayout();
|
||||
gridQuote.Rows.Clear();
|
||||
|
||||
for (int i = 0; i < QuoteItems.Length; i++)
|
||||
{
|
||||
int idx = gridQuote.Rows.Add();
|
||||
gridQuote.Rows[idx].Cells[QCOL_ITEM].Value = QuoteItems[i];
|
||||
gridQuote.Rows[idx].Cells[QCOL_PRICE].Value = "";
|
||||
gridQuote.Rows[idx].Cells[QCOL_QTY].Value = "0";
|
||||
gridQuote.Rows[idx].Cells[QCOL_SUB].Value = "0";
|
||||
}
|
||||
|
||||
gridQuote.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
|
||||
gridQuote.ColumnHeadersHeight = 30;
|
||||
gridQuote.AllowUserToResizeRows = false;
|
||||
DisableAdgvFilterButtons(gridQuote);
|
||||
gridQuote.ClearSelection();
|
||||
gridQuote.ResumeLayout();
|
||||
}
|
||||
|
||||
private void DisableAdgvFilterButtons(Smart.CustomComponents.EnhancedDataGridView grid)
|
||||
{
|
||||
// Smart EnhancedDataGridView 没有内置筛选按钮,无需禁用
|
||||
}
|
||||
|
||||
private void InitDefaultValues()
|
||||
{
|
||||
double cabinetPrice = DefaultCabinetPrice;
|
||||
double[] drawerPrices = (double[])DefaultDrawerPrices.Clone();
|
||||
|
||||
double[] saved = LoadSavedPrices();
|
||||
if (saved != null && saved.Length >= 1 + DefaultDrawerPrices.Length)
|
||||
{
|
||||
cabinetPrice = saved[0];
|
||||
for (int i = 0; i < DefaultDrawerPrices.Length; i++) drawerPrices[i] = saved[1 + i];
|
||||
}
|
||||
|
||||
_isCalculating = true;
|
||||
try
|
||||
{
|
||||
gridQuote.Rows[0].Cells[QCOL_PRICE].Value = cabinetPrice.ToString("0");
|
||||
gridQuote.Rows[0].Cells[QCOL_QTY].Value = DefaultCabinetQty.ToString("0");
|
||||
for (int i = 0; i < DefaultDrawerPrices.Length; i++)
|
||||
{
|
||||
gridQuote.Rows[1 + i].Cells[QCOL_PRICE].Value = drawerPrices[i].ToString("0");
|
||||
gridQuote.Rows[1 + i].Cells[QCOL_QTY].Value = "0";
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isCalculating = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void WireEvents()
|
||||
{
|
||||
gridCurrents.CellValueChanged += gridCurrents_CellValueChanged;
|
||||
gridCurrents.CurrentCellDirtyStateChanged += gridCurrents_CurrentCellDirtyStateChanged;
|
||||
gridCurrents.CellValidating += gridCurrents_CellValidating;
|
||||
|
||||
gridQuote.CellValueChanged += gridQuote_CellValueChanged;
|
||||
gridQuote.CurrentCellDirtyStateChanged += gridQuote_CurrentCellDirtyStateChanged;
|
||||
|
||||
checkBox1.CheckedChanged += checkBox1_CheckedChanged;
|
||||
checkBox2.CheckedChanged += (s, e) => { if (!_isCalculating) RecalculateAll(); };
|
||||
comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
|
||||
|
||||
btnClear.Click += btnClear_Click;
|
||||
button1.Click += button1_Click;
|
||||
button2.Click += button2_Click;
|
||||
button3.Click += button3_Click;
|
||||
|
||||
this.SizeChanged += (s, e) => RelayoutBusbarColumns();
|
||||
}
|
||||
|
||||
private void RelayoutBusbarColumns()
|
||||
{
|
||||
if (gridBusbar.Columns.Count < 2) return;
|
||||
int totalW = gridBusbar.ClientSize.Width;
|
||||
if (totalW <= 20) return;
|
||||
gridBusbar.Columns[0].Width = totalW / 2;
|
||||
gridBusbar.Columns[1].Width = totalW - totalW / 2;
|
||||
}
|
||||
|
||||
private void gridCurrents_CurrentCellDirtyStateChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (gridCurrents.IsCurrentCellDirty)
|
||||
{
|
||||
gridCurrents.CommitEdit(DataGridViewDataErrorContexts.Commit);
|
||||
}
|
||||
}
|
||||
|
||||
private void gridCurrents_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
|
||||
{
|
||||
if (e.RowIndex < 0 || e.RowIndex >= CircuitRows) return;
|
||||
string txt = e.FormattedValue == null ? "" : e.FormattedValue.ToString().Trim();
|
||||
if (txt.Length == 0) return;
|
||||
if (!IsNonNegativeNumber(txt))
|
||||
{
|
||||
e.Cancel = true;
|
||||
MessageBox.Show("请输入有效的电流数值 (≥0)。", "输入错误",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
}
|
||||
}
|
||||
|
||||
private void gridCurrents_CellValueChanged(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
if (_isCalculating) return;
|
||||
if (e.RowIndex < 0 || e.RowIndex >= CircuitRows) return;
|
||||
RecalculateAll();
|
||||
}
|
||||
|
||||
private void gridQuote_CurrentCellDirtyStateChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (gridQuote.IsCurrentCellDirty)
|
||||
{
|
||||
gridQuote.CommitEdit(DataGridViewDataErrorContexts.Commit);
|
||||
}
|
||||
}
|
||||
|
||||
private void gridQuote_CellValueChanged(object sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
if (_isCalculating) return;
|
||||
if (e.RowIndex < 0) return;
|
||||
if (e.ColumnIndex != QCOL_PRICE && e.ColumnIndex != QCOL_QTY) return;
|
||||
RecalculateAll();
|
||||
}
|
||||
|
||||
private void checkBox1_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (_isCalculating) return;
|
||||
RecalculateAll();
|
||||
}
|
||||
|
||||
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (_isCalculating) return;
|
||||
RecalculateAll();
|
||||
// ★不要在这里调 刷新推荐窗口数据()——下拉消息循环期间刷新推荐窗会吞掉
|
||||
// 推荐窗按钮的 Click(2026-09-26 23:36 实测:MouseDown 到达但 Click 全灭)。
|
||||
// 推荐窗在"打开时"和"点插入时"各按当前选定列取数一次(已验证可靠)。
|
||||
}
|
||||
|
||||
private void RecalculateAll()
|
||||
{
|
||||
_isCalculating = true;
|
||||
try
|
||||
{
|
||||
int sel = GetSelectedColumn();
|
||||
RecalculateCurrents(sel);
|
||||
AutoCalcDrawers();
|
||||
RecalculateQuote();
|
||||
UpdateBusbarRecommendation();
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isCalculating = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void RecalculateCurrents(int targetColumn = -1)
|
||||
{
|
||||
_maxLoadCurrent = 0;
|
||||
|
||||
for (int c = 0; c < ColumnCount; c++)
|
||||
{
|
||||
int circuitCount = 0;
|
||||
double sum = 0;
|
||||
for (int r = 0; r < CircuitRows; r++)
|
||||
{
|
||||
double v = GetCellDouble(gridCurrents.Rows[r].Cells[c].Value);
|
||||
if (v > 0)
|
||||
{
|
||||
circuitCount++;
|
||||
sum += v;
|
||||
}
|
||||
}
|
||||
|
||||
double ks = GetKsByCircuitCount(circuitCount);
|
||||
double calcCurrent = sum * ks;
|
||||
|
||||
if (targetColumn < 0 || targetColumn == c)
|
||||
{
|
||||
if (calcCurrent > _maxLoadCurrent)
|
||||
{
|
||||
_maxLoadCurrent = calcCurrent;
|
||||
}
|
||||
}
|
||||
|
||||
for (int s = 0; s < SummaryRows; s++)
|
||||
{
|
||||
double val = sum * SummaryFactors[s];
|
||||
var cell = gridCurrents.Rows[CircuitRows + s].Cells[c];
|
||||
cell.Value = sum > 0 ? FormatCurrent(val) : "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private double GetKsByCircuitCount(int n)
|
||||
{
|
||||
if (n <= 0) return 1.0;
|
||||
if (n == 1) return 1.0;
|
||||
if (n <= 3) return 0.9;
|
||||
if (n <= 5) return 0.8;
|
||||
if (n <= 9) return 0.7;
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
private void AutoCalcDrawers()
|
||||
{
|
||||
int[] counts = new int[7];
|
||||
bool useHalfDrawer = checkBox2 != null && checkBox2.Checked;
|
||||
|
||||
int colStart, colEnd;
|
||||
int sel = GetSelectedColumn();
|
||||
if (sel < 0) { colStart = 0; colEnd = ColumnCount - 1; }
|
||||
else { colStart = sel; colEnd = sel; }
|
||||
|
||||
for (int r = 0; r < CircuitRows; r++)
|
||||
{
|
||||
for (int c = colStart; c <= colEnd; c++)
|
||||
{
|
||||
double v = GetCellDouble(gridCurrents.Rows[r].Cells[c].Value);
|
||||
if (v <= 0) continue;
|
||||
|
||||
int idx = PickDrawerRow(v, useHalfDrawer);
|
||||
if (idx >= 1 && idx <= 6)
|
||||
counts[idx]++;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkBox1 != null && checkBox1.Checked)
|
||||
{
|
||||
for (int i = 1; i <= 6; i++)
|
||||
{
|
||||
gridQuote.Rows[i].Cells[QCOL_QTY].Value = counts[i].ToString("0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int GetSelectedColumn()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (comboBox1 == null || comboBox1.SelectedIndex <= 0) return -1;
|
||||
return comboBox1.SelectedIndex - 1;
|
||||
}
|
||||
catch { return -1; }
|
||||
}
|
||||
|
||||
private int PickDrawerRow(double current, bool useHalfDrawer)
|
||||
{
|
||||
if (current <= 0) return -1;
|
||||
if (useHalfDrawer && current <= 63) return 1;
|
||||
if (current <= 125) return 2;
|
||||
if (current <= 250) return 3;
|
||||
if (current <= 400) return 4;
|
||||
if (current <= 630) return 5;
|
||||
if (current <= 800) return 6;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void RecalculateQuote()
|
||||
{
|
||||
double total = 0;
|
||||
for (int i = 0; i < gridQuote.Rows.Count; i++)
|
||||
{
|
||||
double price = GetCellDouble(gridQuote.Rows[i].Cells[QCOL_PRICE].Value);
|
||||
double qty = GetCellDouble(gridQuote.Rows[i].Cells[QCOL_QTY].Value);
|
||||
double sub = price * qty;
|
||||
gridQuote.Rows[i].Cells[QCOL_SUB].Value = sub.ToString("0.##");
|
||||
total += sub;
|
||||
}
|
||||
lblTotalPrice.Text = total.ToString("0.##");
|
||||
}
|
||||
|
||||
private void UpdateBusbarRecommendation()
|
||||
{
|
||||
string recommend = PickBusbar(_maxLoadCurrent);
|
||||
int recRowIdx = -1;
|
||||
for (int i = 0; i < gridBusbar.Rows.Count; i++)
|
||||
{
|
||||
var row = gridBusbar.Rows[i];
|
||||
bool isRec = recommend != null && BusbarSpecs[i] == recommend;
|
||||
if (isRec) recRowIdx = i;
|
||||
for (int c = 0; c < row.Cells.Count; c++)
|
||||
{
|
||||
row.Cells[c].Style.BackColor = isRec ? RecommendBackColor : Color.White;
|
||||
row.Cells[c].Style.SelectionBackColor = isRec ? RecommendBackColor : Color.White;
|
||||
row.Cells[c].Style.Font = isRec ? new Font("宋体", 9, FontStyle.Bold) : new Font("宋体", 9);
|
||||
}
|
||||
}
|
||||
|
||||
if (recRowIdx >= 0 && recRowIdx < gridBusbar.Rows.Count)
|
||||
{
|
||||
try
|
||||
{
|
||||
gridBusbar.FirstDisplayedScrollingRowIndex = recRowIdx;
|
||||
gridBusbar.CurrentCell = gridBusbar.Rows[recRowIdx].Cells[0];
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
int selCol = GetSelectedColumn();
|
||||
string scope = selCol < 0 ? "全部" : ColumnHeaders[selCol];
|
||||
if (_maxLoadCurrent > 0)
|
||||
{
|
||||
lblRecommend.Text = recommend == null
|
||||
? "推荐铜排 [" + scope + "]: 计算电流 " + _maxLoadCurrent.ToString("0.#") + "A 超出最大规格!"
|
||||
: "推荐铜排 [" + scope + "]: " + recommend + " (计算电流 " + _maxLoadCurrent.ToString("0.#") + "A)";
|
||||
}
|
||||
else
|
||||
{
|
||||
lblRecommend.Text = "推荐铜排: (请先在上方输入各回路电流)";
|
||||
}
|
||||
|
||||
FitRecommendText();
|
||||
}
|
||||
|
||||
private string PickBusbar(double needCurrent)
|
||||
{
|
||||
if (needCurrent <= 0) return null;
|
||||
for (int i = 0; i < BusbarRatings.Length; i++)
|
||||
{
|
||||
if (BusbarRatings[i] >= needCurrent)
|
||||
return BusbarSpecs[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private double GetCellDouble(object value)
|
||||
{
|
||||
if (value == null) return 0;
|
||||
return GetTextDouble(value.ToString());
|
||||
}
|
||||
|
||||
private double GetTextDouble(string s)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(s)) return 0;
|
||||
double v;
|
||||
if (double.TryParse(s.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out v))
|
||||
return v;
|
||||
if (double.TryParse(s.Trim(), NumberStyles.Any, CultureInfo.CurrentCulture, out v))
|
||||
return v;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private bool IsNonNegativeNumber(string s)
|
||||
{
|
||||
double v;
|
||||
if (double.TryParse(s.Trim(), NumberStyles.Any, CultureInfo.InvariantCulture, out v))
|
||||
return v >= 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
private string FormatCurrent(double v)
|
||||
{
|
||||
if (v == 0) return "";
|
||||
if (Math.Abs(v - Math.Round(v)) < 0.001)
|
||||
return Math.Round(v).ToString("0");
|
||||
return v.ToString("0.#");
|
||||
}
|
||||
|
||||
private void btnClear_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (MessageBox.Show("确定要清空所有电流输入和抽屉数量吗?\n(柜体数量保留,单价保留默认值)",
|
||||
"确认清空", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) return;
|
||||
|
||||
for (int r = 0; r < CircuitRows; r++)
|
||||
{
|
||||
for (int c = 0; c < ColumnCount; c++)
|
||||
{
|
||||
gridCurrents.Rows[r].Cells[c].Value = "";
|
||||
}
|
||||
}
|
||||
|
||||
_isCalculating = true;
|
||||
try
|
||||
{
|
||||
for (int i = 1; i < gridQuote.Rows.Count; i++)
|
||||
{
|
||||
gridQuote.Rows[i].Cells[QCOL_QTY].Value = "0";
|
||||
}
|
||||
}
|
||||
finally { _isCalculating = false; }
|
||||
|
||||
RecalculateAll();
|
||||
}
|
||||
|
||||
private string PricesFilePath
|
||||
{
|
||||
get
|
||||
{
|
||||
string dir = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"GCS铜排壳体计算");
|
||||
if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);
|
||||
return Path.Combine(dir, "单价.cfg");
|
||||
}
|
||||
}
|
||||
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
var parts = new List<string>();
|
||||
for (int i = 0; i < gridQuote.Rows.Count; i++)
|
||||
{
|
||||
object v = gridQuote.Rows[i].Cells[QCOL_PRICE].Value;
|
||||
parts.Add(v == null ? "" : v.ToString().Trim());
|
||||
}
|
||||
|
||||
File.WriteAllText(PricesFilePath, string.Join(",", parts),
|
||||
System.Text.Encoding.UTF8);
|
||||
|
||||
MessageBox.Show("单价已保存,下次打开程序将自动使用这些单价。",
|
||||
"保存成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show("保存单价失败: " + ex.Message, "错误",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private double[] LoadSavedPrices()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(PricesFilePath)) return null;
|
||||
string content = File.ReadAllText(PricesFilePath, System.Text.Encoding.UTF8).Trim();
|
||||
if (string.IsNullOrEmpty(content)) return null;
|
||||
string[] parts = content.Split(',');
|
||||
var result = new double[parts.Length];
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
{
|
||||
if (!double.TryParse(parts[i].Trim(), NumberStyles.Any,
|
||||
CultureInfo.InvariantCulture, out result[i])) return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void button2_Click(object sender, EventArgs e)
|
||||
{
|
||||
// 非模态打开推荐铜排窗口,打开时主窗口/GCS窗口仍可点击
|
||||
if (_recommendForm != null && !_recommendForm.IsDisposed)
|
||||
{
|
||||
MainForm.写日志("[推荐铜排] button2:窗口已开,激活已有实例");
|
||||
_recommendForm.Activate();
|
||||
return;
|
||||
}
|
||||
|
||||
int sel = GetSelectedColumn();
|
||||
string scope = sel < 0 ? "全部" : ColumnHeaders[sel];
|
||||
MainForm.写日志("[推荐铜排] button2:新建窗口(范围=" + scope + ", 电流 " + (GetAllCircuitCurrents(sel) == null ? 0 : GetAllCircuitCurrents(sel).Count) + " 个)");
|
||||
_recommendForm = new GCS推荐铜排窗口();
|
||||
_recommendForm.宿主 = this; // ★插入前实时重取回路电流用
|
||||
_recommendForm.SetCircuitCurrents(GetAllCircuitCurrents(sel), scope);
|
||||
_recommendForm.Show(this);
|
||||
_recommendForm.BringToFront(); // ★确保不被主窗口压住(ShowInTaskbar=false 无任务栏按钮)
|
||||
_recommendForm.FormClosed += (s2, e2) => { _recommendForm = null; };
|
||||
}
|
||||
|
||||
/// <summary>★供推荐铜排窗口在点"插入"前实时重取回路电流(2026-09-26 用户报:
|
||||
/// 先开推荐窗后回 GCS 窗输电流,推荐窗还是打开时的旧快照→回路数全 0→插入被"没有铜排"挡住)。
|
||||
/// ★严格按 GCS 窗口当前下拉选定的列统计(用户 2026-09-26 确认:推荐窗必须匹配选择的列,
|
||||
/// 选了 1#/2#/3# 就只算该列;下拉切列时推荐窗实时跟随)。</summary>
|
||||
internal void 刷新推荐窗口数据()
|
||||
{
|
||||
if (_recommendForm == null || _recommendForm.IsDisposed) return;
|
||||
int sel = GetSelectedColumn();
|
||||
var currents = GetAllCircuitCurrents(sel);
|
||||
string scope = sel < 0 ? "全部" : ColumnHeaders[sel];
|
||||
MainForm.写日志("[推荐铜排] 刷新: 范围=" + scope + " 取到 " + (currents == null ? 0 : currents.Count) + " 个回路电流");
|
||||
_recommendForm.SetCircuitCurrents(currents, scope);
|
||||
}
|
||||
|
||||
/// <summary>在打开的窗体中查找主窗口(MyApp.MainForm)实例。</summary>
|
||||
private MainForm FindMainForm()
|
||||
{
|
||||
foreach (Form f in Application.OpenForms)
|
||||
{
|
||||
if (f is MainForm) return (MainForm)f;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// "插入铜排"按钮(button3):把当前推荐的垂直母排规格插入主窗口元件表。
|
||||
/// 规格取 lblRecommend 当前推荐结果(PickBusbar(_maxLoadCurrent)),数量默认 1 米,
|
||||
/// 表价由主窗口按母排界面当前铜价自动计算。
|
||||
/// </summary>
|
||||
private void button3_Click(object sender, EventArgs e)
|
||||
{
|
||||
MainForm main = FindMainForm();
|
||||
if (main == null)
|
||||
{
|
||||
MessageBox.Show("未找到MainForm,无法插入。", "提示",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_maxLoadCurrent <= 0)
|
||||
{
|
||||
MainForm.写日志("[GCS窗口] 插入被防呆挡住: 未输入回路电流(_maxLoadCurrent=0)");
|
||||
MessageBox.Show("请先在上方输入回路电流,计算出推荐铜排后再插入。", "提示",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
string recommend = PickBusbar(_maxLoadCurrent);
|
||||
if (string.IsNullOrEmpty(recommend))
|
||||
{
|
||||
MessageBox.Show("计算电流超出最大铜排规格,无法选型。", "提示",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
if (main.InsertGcs母排(recommend, 1))
|
||||
{
|
||||
MessageBox.Show("已插入垂直母排「" + recommend + "」到报价元件表。", "插入完成",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
}
|
||||
}
|
||||
|
||||
public List<double> GetAllCircuitCurrents(int targetColumn = -1)
|
||||
{
|
||||
var list = new List<double>();
|
||||
int colStart, colEnd;
|
||||
if (targetColumn < 0) { colStart = 0; colEnd = ColumnCount - 1; }
|
||||
else { colStart = targetColumn; colEnd = targetColumn; }
|
||||
|
||||
for (int r = 0; r < CircuitRows; r++)
|
||||
{
|
||||
for (int c = colStart; c <= colEnd; c++)
|
||||
{
|
||||
double v = GetCellDouble(gridCurrents.Rows[r].Cells[c].Value);
|
||||
if (v > 0) list.Add(v);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user