diff --git a/WindowsFormsApp6/Form3.cs b/WindowsFormsApp6/Form3.cs index 9ab5622..cdfebd4 100644 --- a/WindowsFormsApp6/Form3.cs +++ b/WindowsFormsApp6/Form3.cs @@ -265,14 +265,36 @@ namespace WindowsFormsApp6 } } + // 获取当前列名,判断是否是标准偏差列(横向布局) + string colName = ""; + if (e.ColumnIndex < dataGridView1.Columns.Count) + { + colName = dataGridView1.Columns[e.ColumnIndex].Name; + } + + // 判断是否是标准偏差单元格 + bool isStdDeviationCell = (rowName == ROW_STD_DEVIATION) || (colName == ROW_STD_DEVIATION); + // 格式化数值显示为2位小数 if (e.Value != null && e.Value != DBNull.Value) { if (double.TryParse(e.Value.ToString(), out double numValue)) { - // 标准偏差行:即使为0也要显示 - if (rowName == ROW_STD_DEVIATION) + // 标准偏差单元格:检查是否有测试数据 + if (isStdDeviationCell) { + // 检查是否有有效的测试数据(芯吸速率 > 0) + bool hasTestData = HasValidTestData(e.RowIndex); + + if (!hasTestData) + { + // 没有测试数据时,不显示标准偏差 + e.Value = ""; + e.FormattingApplied = true; + return; + } + + // 有测试数据时,显示标准偏差(即使为0也显示) e.Value = numValue.ToString("F2"); e.FormattingApplied = true; return; @@ -299,6 +321,52 @@ namespace WindowsFormsApp6 } } + /// + /// 检查是否有有效的测试数据(芯吸速率 > 0) + /// + private bool HasValidTestData(int rowIndex) + { + if (sampleDataTable == null || sampleDataTable.Rows.Count == 0) + return false; + + if (isVerticalLayout) + { + // 纵向布局:检查芯吸速率行(第3行,索引2) + if (sampleDataTable.Rows.Count <= 2) + return false; + + DataRow rateRow = sampleDataTable.Rows[2]; + for (int i = 1; i <= currentSampleCount; i++) + { + for (int j = 1; j <= 3; j++) + { + string colName = $"试样{i}_{j}"; + if (rateRow.Table.Columns.Contains(colName)) + { + double rate = ConvertToDouble(rateRow[colName]); + if (rate > 0.001) // 有任何一个芯吸速率 > 0,就认为有测试数据 + return true; + } + } + } + } + else + { + // 横向布局:检查当前行及相关行的芯吸速率列 + foreach (DataRow row in sampleDataTable.Rows) + { + if (row.Table.Columns.Contains(ROW_WICKING_RATE)) + { + double rate = ConvertToDouble(row[ROW_WICKING_RATE]); + if (rate > 0.001) // 有任何一个芯吸速率 > 0,就认为有测试数据 + return true; + } + } + } + + return false; + } + /// /// 单元格值改变事件 - 手动输入后重新计算 /// 注意:由于所有单元格都不可编辑,此事件不会被触发 @@ -376,19 +444,20 @@ namespace WindowsFormsApp6 /// public void ToggleTableLayout() { + // 1. 先保存当前数据(明确指定当前布局) + var currentData = SaveCurrentData(isVerticalLayout); + + // 2. 切换布局标志 isVerticalLayout = !isVerticalLayout; - // 保存当前数据 - var currentData = SaveCurrentData(); - - // 重新初始化表格 + // 3. 重新初始化表格(使用新布局) InitializeDataTable(); InitializeDataGridView(); - // 恢复数据 - RestoreData(currentData); + // 4. 恢复数据(转换到新布局) + RestoreData(currentData, isVerticalLayout); - // 更新显示 + // 5. 更新显示 RefreshDataGridView(); ShowMessage($"已切换到{(isVerticalLayout ? "纵向" : "横向")}布局", "布局切换", MessageBoxIcon.Information); @@ -403,61 +472,143 @@ namespace WindowsFormsApp6 } /// - /// 保存当前数据 + /// 保存当前数据 - 精确保存所有测试数据 /// - private Dictionary> SaveCurrentData() + private Dictionary> SaveCurrentData(bool fromVerticalLayout) { var data = new Dictionary>(); if (sampleDataTable == null || sampleDataTable.Rows.Count == 0) return data; - foreach (DataRow row in sampleDataTable.Rows) + if (fromVerticalLayout) { - string rowName = row["序号"]?.ToString() ?? ""; - if (string.IsNullOrEmpty(rowName)) continue; + // 从纵向布局保存:直接保存每行数据 + foreach (DataRow row in sampleDataTable.Rows) + { + string rowName = row["序号"]?.ToString() ?? ""; + if (string.IsNullOrEmpty(rowName)) continue; + + var rowData = new Dictionary(); + for (int i = 1; i <= currentSampleCount; i++) + { + for (int j = 1; j <= 3; j++) + { + string colName = $"试样{i}_{j}"; + if (row.Table.Columns.Contains(colName)) + { + rowData[colName] = ConvertToDouble(row[colName]); + } + } + } + data[rowName] = rowData; + } + } + else + { + // 从横向布局保存:需要转换数据结构 + // 初始化5个数据行 + data[ROW_WICKING_TIME] = new Dictionary(); + data[ROW_WICKING_HEIGHT] = new Dictionary(); + data[ROW_WICKING_RATE] = new Dictionary(); + data[ROW_AVG_WICKING_RATE] = new Dictionary(); + data[ROW_STD_DEVIATION] = new Dictionary(); - var rowData = new Dictionary(); + // 遍历每个试样的每次测试 + int rowIndex = 0; for (int i = 1; i <= currentSampleCount; i++) { for (int j = 1; j <= 3; j++) { - string colName = $"试样{i}_{j}"; - if (row.Table.Columns.Contains(colName)) + if (rowIndex < sampleDataTable.Rows.Count) { - rowData[colName] = ConvertToDouble(row[colName]); + DataRow row = sampleDataTable.Rows[rowIndex]; + string colName = $"试样{i}_{j}"; + + if (row.Table.Columns.Contains(ROW_WICKING_TIME)) + data[ROW_WICKING_TIME][colName] = ConvertToDouble(row[ROW_WICKING_TIME]); + + if (row.Table.Columns.Contains(ROW_WICKING_HEIGHT)) + data[ROW_WICKING_HEIGHT][colName] = ConvertToDouble(row[ROW_WICKING_HEIGHT]); + + if (row.Table.Columns.Contains(ROW_WICKING_RATE)) + data[ROW_WICKING_RATE][colName] = ConvertToDouble(row[ROW_WICKING_RATE]); + + if (row.Table.Columns.Contains(ROW_AVG_WICKING_RATE)) + data[ROW_AVG_WICKING_RATE][colName] = ConvertToDouble(row[ROW_AVG_WICKING_RATE]); + + if (row.Table.Columns.Contains(ROW_STD_DEVIATION)) + data[ROW_STD_DEVIATION][colName] = ConvertToDouble(row[ROW_STD_DEVIATION]); + + rowIndex++; } } } - data[rowName] = rowData; } return data; } /// - /// 恢复数据 + /// 恢复数据 - 精确恢复所有测试数据 /// - private void RestoreData(Dictionary> data) + private void RestoreData(Dictionary> data, bool toVerticalLayout) { if (data == null || data.Count == 0 || sampleDataTable == null) return; - foreach (DataRow row in sampleDataTable.Rows) + if (toVerticalLayout) { - string rowName = row["序号"]?.ToString() ?? ""; - if (string.IsNullOrEmpty(rowName) || !data.ContainsKey(rowName)) - continue; - - var rowData = data[rowName]; + // 恢复到纵向布局:直接恢复每行数据 + foreach (DataRow row in sampleDataTable.Rows) + { + string rowName = row["序号"]?.ToString() ?? ""; + if (string.IsNullOrEmpty(rowName) || !data.ContainsKey(rowName)) + continue; + + var rowData = data[rowName]; + for (int i = 1; i <= currentSampleCount; i++) + { + for (int j = 1; j <= 3; j++) + { + string colName = $"试样{i}_{j}"; + if (row.Table.Columns.Contains(colName) && rowData.ContainsKey(colName)) + { + row[colName] = rowData[colName]; + } + } + } + } + } + else + { + // 恢复到横向布局:需要转换数据结构 + int rowIndex = 0; for (int i = 1; i <= currentSampleCount; i++) { for (int j = 1; j <= 3; j++) { - string colName = $"试样{i}_{j}"; - if (row.Table.Columns.Contains(colName) && rowData.ContainsKey(colName)) + if (rowIndex < sampleDataTable.Rows.Count) { - row[colName] = rowData[colName]; + DataRow row = sampleDataTable.Rows[rowIndex]; + string colName = $"试样{i}_{j}"; + + if (data.ContainsKey(ROW_WICKING_TIME) && data[ROW_WICKING_TIME].ContainsKey(colName)) + row[ROW_WICKING_TIME] = data[ROW_WICKING_TIME][colName]; + + if (data.ContainsKey(ROW_WICKING_HEIGHT) && data[ROW_WICKING_HEIGHT].ContainsKey(colName)) + row[ROW_WICKING_HEIGHT] = data[ROW_WICKING_HEIGHT][colName]; + + if (data.ContainsKey(ROW_WICKING_RATE) && data[ROW_WICKING_RATE].ContainsKey(colName)) + row[ROW_WICKING_RATE] = data[ROW_WICKING_RATE][colName]; + + if (data.ContainsKey(ROW_AVG_WICKING_RATE) && data[ROW_AVG_WICKING_RATE].ContainsKey(colName)) + row[ROW_AVG_WICKING_RATE] = data[ROW_AVG_WICKING_RATE][colName]; + + if (data.ContainsKey(ROW_STD_DEVIATION) && data[ROW_STD_DEVIATION].ContainsKey(colName)) + row[ROW_STD_DEVIATION] = data[ROW_STD_DEVIATION][colName]; + + rowIndex++; } } } @@ -935,12 +1086,12 @@ namespace WindowsFormsApp6 DataRow rateRow = sampleDataTable.Rows[2]; DataRow stdRow = sampleDataTable.Rows[4]; - // 清空标准偏差行的所有数据 + // 清空标准偏差行的所有数据(初始化为0.0,显示时会根据是否有测试数据决定是否显示) for (int i = 1; i <= currentSampleCount; i++) { - stdRow[$"试样{i}_1"] = DBNull.Value; - stdRow[$"试样{i}_2"] = DBNull.Value; - stdRow[$"试样{i}_3"] = DBNull.Value; + stdRow[$"试样{i}_1"] = 0.0; + stdRow[$"试样{i}_2"] = 0.0; + stdRow[$"试样{i}_3"] = 0.0; } // 计算每组(5个试样)的标准偏差 @@ -989,10 +1140,10 @@ namespace WindowsFormsApp6 else { // 横向布局 - // 清空所有行的标准偏差列 + // 清空所有行的标准偏差列(初始化为0.0,显示时会根据是否有测试数据决定是否显示) foreach (DataRow row in sampleDataTable.Rows) { - row[ROW_STD_DEVIATION] = DBNull.Value; + row[ROW_STD_DEVIATION] = 0.0; } // 计算每组(5个试样)的标准偏差 @@ -1037,12 +1188,25 @@ namespace WindowsFormsApp6 stdDev = Math.Sqrt(sumOfSquares / (groupAverages.Count - 1)); } - // 只在该组第1个试样的第1次测试行显示标准偏差,其他行保持DBNull + // 只在该组第1个试样的第1次测试行显示标准偏差,其他行保持0.0 int targetRowIndex = (startSample - 1) * 3; // 第1次测试的行索引 if (targetRowIndex < sampleDataTable.Rows.Count) { sampleDataTable.Rows[targetRowIndex][ROW_STD_DEVIATION] = Math.Round(stdDev, 2); } + + // 其他行保持0.0(不显示) + for (int i = startSample; i <= endSample; i++) + { + for (int j = 1; j <= 3; j++) + { + int rowIdx = (i - 1) * 3 + (j - 1); + if (rowIdx != targetRowIndex && rowIdx < sampleDataTable.Rows.Count) + { + sampleDataTable.Rows[rowIdx][ROW_STD_DEVIATION] = 0.0; + } + } + } } } }