C#运行时将DataGridViewTextBoxCell转为DataGridViewComboBoxCell崩溃如何解决
崩溃原因
- 索引越界:双击DataGridView表头行、底部新增占位行时,
e.RowIndex或e.ColumnIndex为-1,直接访问对应单元格会触发索引越界异常 - 数据验证异常:原单元格(默认是
DataGridViewTextBoxCell)的现有值不在你创建的ComboBox的Items集合中时,DataGridView会抛出数据验证失败的异常,这是最常见的崩溃诱因 - 类型转换异常:未同步原单元格的值到新的ComboBox单元格时,两种单元格类型的取值逻辑不兼容也会触发运行时错误
完整实现代码
首先处理双击替换逻辑,同时支持编辑结束后可选恢复为普通文本单元格:
private void Dgv_Data_List_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { // 跳过表头、占位行、已经是ComboBox的单元格 if (e.RowIndex < 0 || e.ColumnIndex < 0 || Dgv_Data_List.Rows[e.RowIndex].IsNewRow || Dgv_Data_List.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewComboBoxCell) { return; } // 保存原单元格的数值 var originalCell = Dgv_Data_List.Rows[e.RowIndex].Cells[e.ColumnIndex]; var originalValue = originalCell.Value?.ToString(); // 创建ComboBox单元格 DataGridViewComboBoxCell cboCell = new DataGridViewComboBoxCell(); cboCell.Items.AddRange("Yes", "No"); // 同步原数值到ComboBox,避免值不存在的异常 if (!string.IsNullOrEmpty(originalValue) && cboCell.Items.Contains(originalValue)) { cboCell.Value = originalValue; } else { // 原数值不在选项中时默认设为第一项,也可以根据需求调整 cboCell.Value = cboCell.Items[0]; } // 替换单元格 Dgv_Data_List.Rows[e.RowIndex].Cells[e.ColumnIndex] = cboCell; // 自动进入编辑状态 Dgv_Data_List.BeginEdit(true); } // 可选:编辑结束后恢复为普通文本单元格,不需要该逻辑可以删除这个事件 private void Dgv_Data_List_CellEndEdit(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex < 0 || e.ColumnIndex < 0 || Dgv_Data_List.Rows[e.RowIndex].IsNewRow) { return; } if (Dgv_Data_List.Rows[e.RowIndex].Cells[e.ColumnIndex] is DataGridViewComboBoxCell cboCell) { // 把选中的值存到新的文本单元格中 DataGridViewTextBoxCell txtCell = new DataGridViewTextBoxCell(); txtCell.Value = cboCell.Value?.ToString(); Dgv_Data_List.Rows[e.RowIndex].Cells[e.ColumnIndex] = txtCell; } }
注意事项
- 如果你不需要编辑结束后恢复为文本单元格,可以直接删除
CellEndEdit的相关代码,单元格会保持ComboBox状态 - 可以根据业务需求动态修改
cboCell.Items.AddRange的参数,传入不同的选项列表
内容的提问来源于stack exchange,提问作者Frank
相关产品推荐
相关产品推荐

