C#中DataGridView图片预览及赋值到PictureBox显示报错如何解决


问题根因
- 核心错误:更新员工数据的逻辑使用了字符串拼接SQL语句,字节数组类型的图片数据被直接拼接进SQL字符串,C#中字节数组默认ToString()返回值为
System.Byte[],最终存入数据库image字段的是该字符串的二进制内容,并非合法的图片流,读取解析时触发格式异常。插入逻辑使用参数化查询所以写入的数据是正常的,只有经过更新的记录会出现该问题。 - 次要问题:缺少图片空值判断、DataGridView图片列未配置异常兼容规则、内存流未合理释放。
修复步骤
1. 替换更新逻辑为参数化查询
将button2_Click方法中的SQL拼接逻辑替换为参数化写法,和插入逻辑保持一致:
private void button2_Click(object sender, EventArgs e) { // 先判断是否有选中的图片 if(pictureBox1.Image == null) { MessageBox.Show("请先选择图片"); return; } Image img = pictureBox1.Image; byte[] arr; ImageConverter converter = new ImageConverter(); arr = (byte[])converter.ConvertTo(img, typeof(byte[])); try { con.Open(); // 替换为参数化SQL,不要拼接 SqlCommand cmd = new SqlCommand("update EmployeeData set Cnic = @Cnic, DOB=@DOB, Name=@Name,FatherName=@FatherName,Post=@Post,BPS=@BPS,Address= @Address,TownVillage=@TownVillage,BloodGroup= @BloodGroup,MobileNumber=@MobileNumber,PresentWorking=@PresentWorking,JobStatus=@JobStatus,SubOffice=@SubOffice,Image=@Image where AgPersonalNumber =@AgPersonalNumber", con); cmd.Parameters.AddWithValue("@AgPersonalNumber", int.Parse(agpersonaltextbox.Text)); cmd.Parameters.AddWithValue("@Cnic", cnictextbox.Text); cmd.Parameters.AddWithValue("@DOB", Convert.ToDateTime(dobtextbox.Text)); cmd.Parameters.AddWithValue("@Name", nametextbox.Text); cmd.Parameters.AddWithValue("@FatherName", fathernametextbox.Text); cmd.Parameters.AddWithValue("@Post", posttextbox.Text); cmd.Parameters.AddWithValue("@BPS", bpscombobox.Text); cmd.Parameters.AddWithValue("@Address", addresstextbox.Text); cmd.Parameters.AddWithValue("@TownVillage", townvillagetextbox.Text); cmd.Parameters.AddWithValue("@BloodGroup", bloodgroupcombobox.Text); cmd.Parameters.AddWithValue("@MobileNumber", mobilenumbertextbox.Text); cmd.Parameters.AddWithValue("@PresentWorking", presentworkingtextbox.Text); cmd.Parameters.AddWithValue("@JobStatus", jobstatuscombobox.Text); cmd.Parameters.AddWithValue("@SubOffice", subofficetextbox.Text); cmd.Parameters.AddWithValue("@Image", arr); cmd.ExecuteNonQuery(); MessageBox.Show("Updated Successfully"); SqlCommand cmd2 = new SqlCommand("SELECT * FROM EmployeeData", con); DataTable dt = new DataTable(); dt.Load(cmd2.ExecuteReader()); dataGridView3.DataSource = dt; con.Close(); } catch (Exception ex) { MessageBox.Show(" Not Updated " + ex.Message); if(con.State == ConnectionState.Open) con.Close(); } }
2. 优化双击赋值逻辑
增加空值判断,合理释放内存流:
private void dataGridView3_DoubleClick(object sender, EventArgs e) { agpersonaltextbox.Clear(); cnictextbox.Clear(); nametextbox.Clear(); fathernametextbox.Clear(); posttextbox.Clear(); addresstextbox.Clear(); townvillagetextbox.Clear(); mobilenumbertextbox.Clear(); presentworkingtextbox.Clear(); subofficetextbox.Clear(); pictureBox1.Image = null; if (dataGridView3.CurrentRow.Index != -1) { agpersonaltextbox.Text = dataGridView3.CurrentRow.Cells[0].Value.ToString(); cnictextbox.Text = dataGridView3.CurrentRow.Cells[1].Value.ToString(); dobtextbox.Text = dataGridView3.CurrentRow.Cells[2].Value.ToString(); nametextbox.Text = dataGridView3.CurrentRow.Cells[3].Value.ToString(); fathernametextbox.Text = dataGridView3.CurrentRow.Cells[4].Value.ToString(); posttextbox.Text = dataGridView3.CurrentRow.Cells[5].Value.ToString(); bpscombobox.Text = dataGridView3.CurrentRow.Cells[6].Value.ToString(); addresstextbox.Text = dataGridView3.CurrentRow.Cells[7].Value.ToString(); townvillagetextbox.Text = dataGridView3.CurrentRow.Cells[8].Value.ToString(); bloodgroupcombobox.Text = dataGridView3.CurrentRow.Cells[9].Value.ToString(); mobilenumbertextbox.Text = dataGridView3.CurrentRow.Cells[10].Value.ToString(); presentworkingtextbox.Text = dataGridView3.CurrentRow.Cells[11].Value.ToString(); jobstatuscombobox.Text = dataGridView3.CurrentRow.Cells[12].Value.ToString(); subofficetextbox.Text = dataGridView3.CurrentRow.Cells[13].Value.ToString(); // 增加空值和格式判断 if(dataGridView3.CurrentRow.Cells[14].Value != DBNull.Value && dataGridView3.CurrentRow.Cells[14].Value is byte[] imgdata && imgdata.Length > 0) { try { using(MemoryStream ms = new MemoryStream(imgdata)) { pictureBox1.Image = Image.FromStream(ms); } } catch(Exception ex) { MessageBox.Show("图片解析失败:" + ex.Message); pictureBox1.Image = null; } } } }
3. 配置DataGridView图片列兼容异常
在Form_Load绑定数据后配置图片列,避免滑动时报错:
private void Form3_Load(object sender, EventArgs e) { con.Open(); SqlCommand cmd2 = new SqlCommand("SELECT * FROM EmployeeData", con); DataTable dt = new DataTable(); dt.Load(cmd2.ExecuteReader()); con.Close(); dataGridView3.DataSource = dt; // 配置图片列 if (dataGridView3.Columns[14] is DataGridViewImageColumn imgCol) { imgCol.DefaultCellStyle.NullValue = null; imgCol.ErrorText = "图片加载失败"; imgCol.ImageLayout = DataGridViewImageCellLayout.Zoom; } }
4. 清理错误历史数据
删除之前更新操作错误写入的记录,或者重新上传图片更新为正确的二进制数据,避免旧记录继续触发异常。
内容的提问来源于stack exchange,提问作者umer mughal
相关产品推荐
相关产品推荐

