209 lines
6.4 KiB
Plaintext
209 lines
6.4 KiB
Plaintext
吸芯高度全列可编辑 - 实现说明
|
||
=========================================
|
||
|
||
## 需求
|
||
用户要求"吸芯高度(mm)"行的所有列(试样次数1、2、3)都可以编辑,而不是只有试样次数2列可编辑。
|
||
|
||
## 实现方案
|
||
|
||
### 1. 动态控制可编辑性
|
||
不再通过列的ReadOnly属性固定控制,而是通过CellBeginEdit事件动态判断:
|
||
- 所有列的ReadOnly属性设置为false
|
||
- 在CellBeginEdit事件中判断当前行是否为"吸芯高度(mm)"
|
||
- 如果是吸芯高度行,允许编辑(return)
|
||
- 如果是其他行,取消编辑(e.Cancel = true)
|
||
|
||
### 2. 代码修改
|
||
|
||
#### 修改1:列定义(InitializeDataGridView方法)
|
||
```csharp
|
||
// 修改前:
|
||
ReadOnly = true, // 试样次数1列
|
||
ReadOnly = false, // 试样次数2列
|
||
ReadOnly = true, // 试样次数3列
|
||
|
||
// 修改后:
|
||
ReadOnly = false, // 所有列都设置为false
|
||
ReadOnly = false,
|
||
ReadOnly = false,
|
||
```
|
||
|
||
#### 修改2:添加CellBeginEdit事件处理
|
||
```csharp
|
||
// 新增方法
|
||
private void DataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
|
||
{
|
||
if (e.RowIndex >= 0 && e.ColumnIndex > 0) // 跳过序号列
|
||
{
|
||
string rowName = dataGridView1.Rows[e.RowIndex].Cells["序号"].Value?.ToString() ?? "";
|
||
|
||
// 吸芯高度(mm)行 - 所有列都可以编辑
|
||
if (rowName == "吸芯高度(mm)")
|
||
{
|
||
return; // 允许编辑
|
||
}
|
||
|
||
// 其他行 - 取消编辑
|
||
e.Cancel = true;
|
||
}
|
||
}
|
||
|
||
// 在InitializeDataGridView方法中注册事件
|
||
dataGridView1.CellBeginEdit += DataGridView1_CellBeginEdit;
|
||
```
|
||
|
||
#### 修改3:更新CellValueChanged事件
|
||
```csharp
|
||
// 修改前:判断列名是否包含"_2"
|
||
if (columnName.Contains("_2"))
|
||
{
|
||
RecalculateRow(e.RowIndex);
|
||
}
|
||
|
||
// 修改后:判断行名是否为"吸芯高度(mm)"
|
||
string rowName = dataGridView1.Rows[e.RowIndex].Cells["序号"].Value?.ToString() ?? "";
|
||
if (rowName == "吸芯高度(mm)")
|
||
{
|
||
RecalculateRow(e.RowIndex);
|
||
}
|
||
```
|
||
|
||
#### 修改4:更新ShouldBeEmpty方法
|
||
```csharp
|
||
// 修改前:
|
||
if (rowName == "吸芯高度(mm)")
|
||
{
|
||
return columnName.EndsWith("_1") || columnName.EndsWith("_3");
|
||
}
|
||
|
||
// 修改后:
|
||
if (rowName == "吸芯高度(mm)")
|
||
{
|
||
return false; // 不应该为空,所有列都有数据
|
||
}
|
||
```
|
||
|
||
#### 修改5:更新CalculateWickingRate方法
|
||
```csharp
|
||
// 修改前:只使用试样次数2列的吸芯高度
|
||
double height = Convert.ToDouble(heightRow[$"试样{i}_2"]);
|
||
|
||
// 修改后:使用所有列的平均值
|
||
double height1 = Convert.ToDouble(heightRow[$"试样{i}_1"]);
|
||
double height2 = Convert.ToDouble(heightRow[$"试样{i}_2"]);
|
||
double height3 = Convert.ToDouble(heightRow[$"试样{i}_3"]);
|
||
|
||
double avgHeight = 0;
|
||
int count = 0;
|
||
if (height1 > 0) { avgHeight += height1; count++; }
|
||
if (height2 > 0) { avgHeight += height2; count++; }
|
||
if (height3 > 0) { avgHeight += height3; count++; }
|
||
|
||
if (count > 0)
|
||
{
|
||
avgHeight /= count;
|
||
rate = avgHeight / (time / 60.0);
|
||
}
|
||
```
|
||
|
||
#### 修改6:更新GenerateMockData方法
|
||
```csharp
|
||
// 修改前:只生成试样次数2列的数据
|
||
heightRow[$"试样{i}_2"] = Math.Round(50 + random.NextDouble() * 20, 2);
|
||
|
||
// 修改后:生成所有3列的数据
|
||
heightRow[$"试样{i}_1"] = Math.Round(50 + random.NextDouble() * 20, 2);
|
||
heightRow[$"试样{i}_2"] = Math.Round(50 + random.NextDouble() * 20, 2);
|
||
heightRow[$"试样{i}_3"] = Math.Round(50 + random.NextDouble() * 20, 2);
|
||
```
|
||
|
||
### 3. 文档更新
|
||
|
||
#### 更新的文档文件:
|
||
1. **手动输入功能说明.txt**
|
||
- 更新可编辑列说明:所有3列都可编辑
|
||
- 更新操作流程
|
||
- 添加Q6:为什么所有列都可以编辑
|
||
|
||
2. **表格数据分布说明.txt**
|
||
- 更新表格示意图:吸芯高度行所有列标记为[可编辑]
|
||
- 更新数据存储位置说明
|
||
- 更新实现要点
|
||
|
||
3. **快速测试手动输入.txt**
|
||
- 添加测试步骤3、4、5:分别测试3列的编辑
|
||
- 更新预期结果示意图
|
||
- 更新检查点
|
||
- 添加重要提示
|
||
|
||
## 实现效果
|
||
|
||
### 用户体验
|
||
1. 双击吸芯高度行的任意列(试样次数1、2或3)都可以进入编辑模式
|
||
2. 输入数值后按Enter键确认
|
||
3. 系统自动计算芯吸速率(使用所有非零值的平均值)
|
||
4. 平均芯吸速率和标准偏差自动更新
|
||
5. 其他行(吸水时间、芯吸速率等)保持只读,无法编辑
|
||
|
||
### 数据计算
|
||
- 芯吸速率 = 平均吸芯高度 / (吸水时间 / 60)
|
||
- 平均吸芯高度 = (试样次数1 + 试样次数2 + 试样次数3) / 非零值数量
|
||
- 这样可以更灵活地处理数据,用户可以在任意列输入
|
||
|
||
### 视觉反馈
|
||
- 可编辑单元格选中时:蓝色背景(LightBlue)
|
||
- 只读单元格选中时:灰色背景(LightGray)
|
||
- 隔行变色:黄色(RGB 255,255,200)和白色交替
|
||
|
||
## 测试验证
|
||
|
||
### 测试步骤
|
||
1. 启动程序,打开Form3
|
||
2. 点击"模拟数据"按钮
|
||
3. 双击吸芯高度行的试样1_1列,输入75.50
|
||
4. 双击吸芯高度行的试样2_2列,输入80.25
|
||
5. 双击吸芯高度行的试样3_3列,输入68.75
|
||
6. 观察芯吸速率是否自动计算
|
||
7. 尝试双击其他行,确认无法编辑
|
||
|
||
### 预期结果
|
||
✅ 吸芯高度行的所有3列都可以编辑
|
||
✅ 其他行的所有单元格都不可编辑
|
||
✅ 编辑后自动计算功能正常
|
||
✅ 隔行变色效果正常
|
||
✅ Excel导出功能正常
|
||
|
||
## 技术要点
|
||
|
||
### 优势
|
||
1. **灵活性**:用户可以在任意列输入数据
|
||
2. **准确性**:使用平均值计算,减少误差
|
||
3. **可维护性**:通过事件动态控制,易于扩展
|
||
4. **用户友好**:视觉反馈清晰,操作直观
|
||
|
||
### 注意事项
|
||
1. CellBeginEdit事件必须在InitializeDataGridView方法中注册
|
||
2. 判断行名时要使用完整的行名"吸芯高度(mm)"
|
||
3. 计算平均值时要排除0值
|
||
4. 所有列的ReadOnly属性必须设置为false
|
||
|
||
## 相关文件
|
||
|
||
### 修改的文件
|
||
- WindowsFormsApp6/Form3.cs(主要实现)
|
||
- WindowsFormsApp6/手动输入功能说明.txt
|
||
- WindowsFormsApp6/表格数据分布说明.txt
|
||
- WindowsFormsApp6/快速测试手动输入.txt
|
||
|
||
### 新增的文件
|
||
- WindowsFormsApp6/吸芯高度全列可编辑实现说明.txt(本文件)
|
||
|
||
## 总结
|
||
|
||
通过动态控制单元格的可编辑性,成功实现了"吸芯高度(mm)"行的所有列都可以编辑的需求。
|
||
这种实现方式比固定设置ReadOnly属性更灵活,也更易于维护和扩展。
|
||
|
||
实现日期:2025-12-30
|
||
实现状态:✅ 完成
|
||
测试状态:⏳ 待测试
|