This commit is contained in:
GukSang.Jin
2026-01-06 15:00:53 +08:00
parent 36f9b3b965
commit b2b3aeea9c

View File

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