C# DataGridView批量设置单元格值:含时段跳过逻辑求助
解决方案:按组分配考试时间并跳过休息时段
我明白你现在的核心需求是按固定行数(slot)为一组批量设置时间,同时遇到休息时段时自动跳过,直接用休息结束时间作为该组的时间,之后继续按规则累加。下面是修改后的完整代码,我会在后面拆解关键改动点:
private void toolStripTextBoxoraSpeaking_KeyUp(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Enter) { // 先验证输入是否为空 if (string.IsNullOrWhiteSpace(toolStripTextBoxoraSpeaking.Text)) { MessageBox.Show("请输入有效的Speaking时间!", "提示!"); return; } try { // 解析所有输入参数 TimeSpan currentGroupStartTime = TimeSpan.Parse(toolStripTextBoxoraSpeaking.Text); int durationExamMinutes = Convert.ToInt32(txtboxDiarkeiaExetasis.Text); int slotSize = Convert.ToInt32(txtboxSlot.Text); TimeSpan breakStartTime = TimeSpan.Parse(txtboxDialimaApo.Text); TimeSpan breakEndTime = TimeSpan.Parse(txtboxDialimaEos.Text); TimeSpan examDuration = TimeSpan.FromMinutes(durationExamMinutes); // 获取所有选中的行,转成列表方便处理 List<DataGridViewRow> selectedRows = dataGridViewYoungLearnersEggrafes.SelectedRows.Cast<DataGridViewRow>().ToList(); int totalSelectedRows = selectedRows.Count; if (totalSelectedRows == 0) { MessageBox.Show("请先选中要设置时间的行!", "提示!"); return; } // 按组循环处理 for (int groupIndex = 0; groupIndex < totalSelectedRows; groupIndex += slotSize) { TimeSpan groupTimeToSet = currentGroupStartTime; // 检查当前组的起始时间是否落在休息时段内 if (currentGroupStartTime >= breakStartTime && currentGroupStartTime < breakEndTime) { // 如果在休息时段,使用休息结束时间作为该组的时间 groupTimeToSet = breakEndTime; // 下一组的起始时间从休息结束时间开始累加考试时长 currentGroupStartTime = breakEndTime + examDuration; } else { // 不在休息时段,下一组起始时间=当前组起始时间+考试时长 currentGroupStartTime += examDuration; } // 为当前组的每一行设置时间(处理最后一组可能不足slot的情况) int rowsInThisGroup = Math.Min(slotSize, totalSelectedRows - groupIndex); for (int rowInGroup = 0; rowInGroup < rowsInThisGroup; rowInGroup++) { int rowIndex = groupIndex + rowInGroup; selectedRows[rowIndex].Cells["timeSpeakingDataGridViewTextBoxColumn"].Value = groupTimeToSet; } } // 保存数据到数据库 BSProgrammaExetaseonYoungLearnersEggrafes.EndEdit(); programmaExetaseonYoung_Learners_Starters_MoversFlyersEggrafesTableAdapter.Connection = MyConn; programmaExetaseonYoung_Learners_Starters_MoversFlyersEggrafesTableAdapter.Update(DSPerioxes_EidoiEksetaseonNew.ProgrammaExetaseonYoung_Learners_Starters_MoversFlyersEggrafes); toolStripTextBoxoraSpeaking.Clear(); MessageBox.Show("时间设置已完成!", "提示!"); } catch (FormatException ex) { // 捕获输入格式错误的异常,给用户提示 MessageBox.Show($"输入格式有误:{ex.Message}\n请确保所有输入符合要求(整数/正确时间格式)!", "错误!"); } catch (Exception ex) { MessageBox.Show($"操作出错:{ex.Message}", "错误!"); } } }
关键改动说明:
- 按组批量处理:不再逐行循环,而是以
slotSize为步长循环分组,每组内的所有行使用同一个时间,彻底解决了原来逐行累加的问题。 - 休息时段判断逻辑:在处理每组前,先检查当前组的起始时间是否落在休息区间内。如果是,直接用休息结束时间作为该组的时间,并且后续组的起始时间从休息结束时间开始计算,确保跳过整个休息时段。
- 边界处理:用
Math.Min(slotSize, totalSelectedRows - groupIndex)处理最后一组可能不足slotSize行的情况,避免索引越界报错。 - 输入验证与异常捕获:增加了空值检查和异常捕获,避免因输入格式错误导致程序崩溃,同时给用户更友好的提示信息。
- 变量名优化:把原来的模糊变量名改成更易懂的名称(比如
duration改成examDuration),同时保留了你原有的控件变量名,确保代码可以直接替换使用。
额外建议:
为了让程序更健壮,你还可以在输入阶段就做前置验证:
- 给
txtboxSlot和txtboxDiarkeiaExetasis添加输入限制,只允许输入正整数。 - 给时间输入框添加格式验证,确保输入的是
HH:mm格式的有效时间。
内容的提问来源于stack exchange,提问作者Vagelis Daldavanis
相关产品推荐
相关产品推荐

