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位小数
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
}
}
/// <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>
/// 单元格值改变事件 - 手动输入后重新计算
/// 注意:由于所有单元格都不可编辑,此事件不会被触发
@@ -376,19 +444,20 @@ namespace WindowsFormsApp6
/// </summary>
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,15 +472,18 @@ namespace WindowsFormsApp6
}
/// <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>>();
if (sampleDataTable == null || sampleDataTable.Rows.Count == 0)
return data;
if (fromVerticalLayout)
{
// 从纵向布局保存:直接保存每行数据
foreach (DataRow row in sampleDataTable.Rows)
{
string rowName = row["序号"]?.ToString() ?? "";
@@ -431,18 +503,63 @@ namespace WindowsFormsApp6
}
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>();
// 遍历每个试样的每次测试
int rowIndex = 0;
for (int i = 1; i <= currentSampleCount; i++)
{
for (int j = 1; j <= 3; j++)
{
if (rowIndex < sampleDataTable.Rows.Count)
{
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++;
}
}
}
}
return data;
}
/// <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)
return;
if (toVerticalLayout)
{
// 恢复到纵向布局:直接恢复每行数据
foreach (DataRow row in sampleDataTable.Rows)
{
string rowName = row["序号"]?.ToString() ?? "";
@@ -463,6 +580,40 @@ namespace WindowsFormsApp6
}
}
}
else
{
// 恢复到横向布局:需要转换数据结构
int rowIndex = 0;
for (int i = 1; i <= currentSampleCount; i++)
{
for (int j = 1; j <= 3; j++)
{
if (rowIndex < sampleDataTable.Rows.Count)
{
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++;
}
}
}
}
}
/// <summary>
/// 连接设备按钮点击事件
@@ -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;
}
}
}
}
}
}