DataGridView空单元格点击引发System.InvalidCastException异常求助
解决DataGridView点击空单元格时的System.InvalidCastException异常
问题分析
你碰到的这个System.InvalidCastException(无法将DBNull转换为byte[]),原因很直接:当你点击DataGridView里的空单元格,或者这条记录的图片字段本身就是NULL值时,dataGridView1.SelectedRows[0].Cells[12].Value返回的是DBNull.Value,而你直接用(byte[])强制转换,这肯定会报错——DBNull和byte[]完全是两种类型,根本没法直接转换。
另外还有个隐藏坑:如果用户点击的是DataGridView的表头,或者没有选中任何有效行,dataGridView1.SelectedRows[0]还会抛出索引越界的异常,这个也得一起处理掉。
修复后的代码
把你的dataGridView1_CellClick方法改成下面这样,增加空值判断和行有效性检查:
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) { // 先判断是否点击的是有效数据行(不是表头,且选中了至少一行) if (e.RowIndex < 0 || dataGridView1.SelectedRows.Count == 0) return; var selectedRow = dataGridView1.SelectedRows[0]; // 处理Staff_Id,先判断单元格值是否为DBNull if (selectedRow.Cells[0].Value != DBNull.Value) { staff_Id = Convert.ToInt32(selectedRow.Cells[0].Value); } else { staff_Id = 0; // 或者设置一个符合你业务逻辑的默认值 } // 文本框赋值时,先判断是否为DBNull,避免ToString()报错 txt_name.Text = selectedRow.Cells[1].Value != DBNull.Value ? selectedRow.Cells[1].Value.ToString() : string.Empty; txt_fathername.Text = selectedRow.Cells[2].Value != DBNull.Value ? selectedRow.Cells[2].Value.ToString() : string.Empty; txt_city.Text = selectedRow.Cells[3].Value != DBNull.Value ? selectedRow.Cells[3].Value.ToString() : string.Empty; txt_address.Text = selectedRow.Cells[4].Value != DBNull.Value ? selectedRow.Cells[4].Value.ToString() : string.Empty; txt_mobileno.Text = selectedRow.Cells[5].Value != DBNull.Value ? selectedRow.Cells[5].Value.ToString() : string.Empty; txt_email.Text = selectedRow.Cells[6].Value != DBNull.Value ? selectedRow.Cells[6].Value.ToString() : string.Empty; txt_cnic.Text = selectedRow.Cells[7].Value != DBNull.Value ? selectedRow.Cells[7].Value.ToString() : string.Empty; txt_education.Text = selectedRow.Cells[8].Value != DBNull.Value ? selectedRow.Cells[8].Value.ToString() : string.Empty; txt_experience.Text = selectedRow.Cells[9].Value != DBNull.Value ? selectedRow.Cells[9].Value.ToString() : string.Empty; txt_subject.Text = selectedRow.Cells[10].Value != DBNull.Value ? selectedRow.Cells[10].Value.ToString() : string.Empty; txt_designation.Text = selectedRow.Cells[11].Value != DBNull.Value ? selectedRow.Cells[11].Value.ToString() : string.Empty; // 重点处理图片列的DBNull情况 if (selectedRow.Cells[12].Value != DBNull.Value && selectedRow.Cells[12].Value is byte[] bytes) { using (MemoryStream ms = new MemoryStream(bytes)) { pic_staff.Image = Image.FromStream(ms); } } else { // 如果没有图片,清空PictureBox或者设置默认图片 pic_staff.Image = null; // 也可以设置项目里的默认图片:pic_staff.Image = Properties.Resources.DefaultAvatar; } }
关键改进点
- 行有效性检查:先判断
e.RowIndex < 0(点击表头)或者SelectedRows.Count == 0的情况,直接返回,避免索引越界。 - DBNull判断:每个单元格赋值前都先检查是否为
DBNull.Value,文本框用三元运算符转成空字符串,避免在DBNull上调用ToString()报错。 - 图片列安全转换:用
is运算符安全判断是否为byte[],如果是再转换,否则清空PictureBox,彻底解决InvalidCastException。 - using语句管理MemoryStream:确保流资源被正确释放,避免内存泄漏。
额外小建议
- 你在
btn_save_Click里的数据库操作,建议用using包裹SqlCommand、FileStream、BinaryReader这些实现了IDisposable的对象,确保资源能及时释放。 - 注意到你INSERT语句里没写
@Staff_Id对应的字段,但参数里加了这个,检查下SQL语句是否和参数匹配,避免出现其他数据库操作错误。
内容的提问来源于stack exchange,提问作者gmJ
相关产品推荐
相关产品推荐

