VB.NET报错:从类型'DBNull'到'String'转换无效的解决方法
VB.NET DataGridView赋值提示DBNull转String无效的解决方案
错误原因
报错conversion from type 'DBNull' to type 'string' is not valid的核心原因是:DataGridView绑定的数据源中存在数据库空值(即DBNull.Value),直接将单元格的DBNull类型值赋值给String类型的文本框Text属性时,VB.NET无法完成隐式类型转换,直接抛出运行时异常。
原始代码未对单元格空值做任何校验,只要某行某列存在空值,对应位置的赋值语句就会触发报错。另外原始代码没有判断点击位置是否为有效数据行,点击列头时还可能触发空引用错误。
修复方案
基础修复(直接替换原有事件代码)
核心逻辑是对每个单元格取值前先判断是否为DBNull,空值则赋值空字符串,非空值再转成字符串赋值给文本框,同时增加行索引有效性判断:
Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick ' 点击列头等非数据行区域时直接退出,避免空引用报错 If e.RowIndex < 0 Then Exit Sub ' 逐字段判断DBNull后赋值 txt_ID.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(0).Value), "", DataGridView1.CurrentRow.Cells(0).Value.ToString()) txt_DATE.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(1).Value), "", DataGridView1.CurrentRow.Cells(1).Value.ToString()) txt_FNAME.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(2).Value), "", DataGridView1.CurrentRow.Cells(2).Value.ToString()) txt_LNAME.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(3).Value), "", DataGridView1.CurrentRow.Cells(3).Value.ToString()) txt_AGE.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(4).Value), "", DataGridView1.CurrentRow.Cells(4).Value.ToString()) txt_SEX.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(5).Value), "", DataGridView1.CurrentRow.Cells(5).Value.ToString()) txt_REGNO.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(6).Value), "", DataGridView1.CurrentRow.Cells(6).Value.ToString()) txt_ROOMNO.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(7).Value), "", DataGridView1.CurrentRow.Cells(7).Value.ToString()) txt_HEIGHT.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(8).Value), "", DataGridView1.CurrentRow.Cells(8).Value.ToString()) txt_WEIGHT.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(9).Value), "", DataGridView1.CurrentRow.Cells(9).Value.ToString()) txt_CELLNO.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(10).Value), "", DataGridView1.CurrentRow.Cells(10).Value.ToString()) txt_ADDRESS.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(11).Value), "", DataGridView1.CurrentRow.Cells(11).Value.ToString()) txt_TELLNO.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(12).Value), "", DataGridView1.CurrentRow.Cells(12).Value.ToString()) txt_FAXNO.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(13).Value), "", DataGridView1.CurrentRow.Cells(13).Value.ToString()) txt_EMAIL.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(14).Value), "", DataGridView1.CurrentRow.Cells(14).Value.ToString()) txt_REFERMD.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(15).Value), "", DataGridView1.CurrentRow.Cells(15).Value.ToString()) txt_MD.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(16).Value), "", DataGridView1.CurrentRow.Cells(16).Value.ToString()) txt_ANES.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(17).Value), "", DataGridView1.CurrentRow.Cells(17).Value.ToString()) txt_PROC.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(18).Value), "", DataGridView1.CurrentRow.Cells(18).Value.ToString()) txt_INDICATION.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(19).Value), "", DataGridView1.CurrentRow.Cells(19).Value.ToString()) txt_XRAY.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(20).Value), "", DataGridView1.CurrentRow.Cells(20).Value.ToString()) txt_TARGET.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(21).Value), "", DataGridView1.CurrentRow.Cells(21).Value.ToString()) txt_PREP1.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(22).Value), "", DataGridView1.CurrentRow.Cells(22).Value.ToString()) txt_PREP2.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(23).Value), "", DataGridView1.CurrentRow.Cells(23).Value.ToString()) txt_PREP3.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(24).Value), "", DataGridView1.CurrentRow.Cells(24).Value.ToString()) txt_QUALITY.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(25).Value), "", DataGridView1.CurrentRow.Cells(25).Value.ToString()) txt_SEGMENT.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(26).Value), "", DataGridView1.CurrentRow.Cells(26).Value.ToString()) txt_BBP.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(27).Value), "", DataGridView1.CurrentRow.Cells(27).Value.ToString()) txt_PREMED.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(28).Value), "", DataGridView1.CurrentRow.Cells(28).Value.ToString()) txt_SCOPE.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(29).Value), "", DataGridView1.CurrentRow.Cells(29).Value.ToString()) txt_PROCTIME.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(30).Value), "", DataGridView1.CurrentRow.Cells(30).Value.ToString()) txt_FINDINGS.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(31).Value), "", DataGridView1.CurrentRow.Cells(31).Value.ToString()) txt_BIOPSY.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(32).Value), "", DataGridView1.CurrentRow.Cells(32).Value.ToString()) txt_LOC.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(33).Value), "", DataGridView1.CurrentRow.Cells(33).Value.ToString()) txt_CYTOLOGY.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(34).Value), "", DataGridView1.CurrentRow.Cells(34).Value.ToString()) txt_SIZE.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(35).Value), "", DataGridView1.CurrentRow.Cells(35).Value.ToString()) txt_ENDODESC.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(36).Value), "", DataGridView1.CurrentRow.Cells(36).Value.ToString()) txt_THERAPEUTIC.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(37).Value), "", DataGridView1.CurrentRow.Cells(37).Value.ToString()) txt_COMPLICATIONS.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(38).Value), "", DataGridView1.CurrentRow.Cells(38).Value.ToString()) txt_DIAGNOSIS.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(39).Value), "", DataGridView1.CurrentRow.Cells(39).Value.ToString()) txt_OUTCOME.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(40).Value), "", DataGridView1.CurrentRow.Cells(40).Value.ToString()) txt_LATECOMP.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(41).Value), "", DataGridView1.CurrentRow.Cells(41).Value.ToString()) txt_HISTOPATH.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(42).Value), "", DataGridView1.CurrentRow.Cells(42).Value.ToString()) txt_ENDOSPCOPIST.Text = If(IsDBNull(DataGridView1.CurrentRow.Cells(43).Value), "", DataGridView1.CurrentRow.Cells(43).Value.ToString()) End Sub
优化写法(减少重复代码)
逐行写判断逻辑重复度高,可以封装一个通用的单元格取值函数,统一处理空值、格式问题:
''' <summary> ''' 安全获取DataGridView单元格的字符串值 ''' </summary> ''' <param name="cell">目标单元格对象</param> ''' <returns>空值返回空字符串,非空值返回去除首尾空格的字符串内容</returns> Private Function GetSafeCellText(cell As DataGridViewCell) As String If cell Is Nothing OrElse cell.Value Is Nothing OrElse IsDBNull(cell.Value) Then Return String.Empty End If Return cell.Value.ToString().Trim() End Function
封装后赋值语句可以大幅简化,示例:
txt_ID.Text = GetSafeCellText(DataGridView1.CurrentRow.Cells(0)) txt_DATE.Text = GetSafeCellText(DataGridView1.CurrentRow.Cells(1)) ' 其余字段按相同格式调用即可
后续如果需要统一增加文本格式化、特殊字符处理逻辑,只需要修改GetSafeCellText函数内部,不需要逐行调整赋值代码。
额外交互优化
当前使用的CellContentClick事件只有点击到单元格内的实际内容时才会触发,点击单元格空白区域、用键盘上下切换选中行时不会执行加载逻辑。如果需要行选中状态变化就自动加载数据,可以把逻辑迁移到SelectionChanged事件中,适配更多操作场景。
内容的提问来源于stack exchange,提问作者Lloyd Merwyn Mandanas
相关产品推荐
相关产品推荐

