C#中DataGridView数据绑定后无法为图片列添加图片
解决DataGridView绑定数据后无法设置图片列的问题
我来帮你搞定这个问题——之前做项目的时候也碰到过一模一样的情况,核心原因是数据绑定会改变DataGridView列的生成逻辑和单元格值的可操作时机,直接手动加列和设置图片没问题,但绑定数据源后就会有干扰。结合你的代码片段,给你两个实用的解决方案:
方案一:禁用自动列生成,手动定义列并在绑定完成后设置图片
当你用DataAdapter绑定数据源时,DataGridView默认会根据数据源的字段自动生成列(AutoGenerateColumns默认是true),这会覆盖你手动创建的图片列,或者让你无法正确设置单元格图片。解决步骤如下:
禁用自动列生成
在绑定数据源前,先把AutoGenerateColumns设为false,这样控件只会用你手动创建的列:dataGridView1.AutoGenerateColumns = false;手动创建所有需要的列
包括你的数据列和图片列,注意给数据列指定DataPropertyName和数据源的字段对应:// 创建RegistryTypeId列 DataGridViewTextBoxColumn idColumn = new DataGridViewTextBoxColumn(); idColumn.DataPropertyName = "RegistryTypeId"; idColumn.HeaderText = "ID"; dataGridView1.Columns.Add(idColumn); // 创建描述列 DataGridViewTextBoxColumn descColumn = new DataGridViewTextBoxColumn(); descColumn.DataPropertyName = "RegistryTypeDescription"; descColumn.HeaderText = "描述"; dataGridView1.Columns.Add(descColumn); // 创建图片列,注意给列命名方便后续访问 DataGridViewImageColumn imageColumn = new DataGridViewImageColumn(); imageColumn.HeaderText = "图标"; imageColumn.Name = "IconColumn"; dataGridView1.Columns.Add(imageColumn);绑定数据源并在绑定完成后设置图片
绑定数据源后,不能立刻设置图片,要等到DataBindingComplete事件触发(此时所有行都已生成),再遍历行设置图片:// 绑定数据源 dataGridView1.DataSource = ds.Tables[0]; // 给DataGridView添加DataBindingComplete事件处理 dataGridView1.DataBindingComplete += dataGridView1_DataBindingComplete;然后实现事件方法:
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e) { foreach (DataGridViewRow row in dataGridView1.Rows) { // 跳过新行(如果允许添加的话) if (row.IsNewRow) continue; // 根据RegistryTypeId判断要显示的图片 int registryTypeId = Convert.ToInt32(row.Cells["RegistryTypeId"].Value); if (registryTypeId == 1) { row.Cells["IconColumn"].Value = Properties.Resources.DocumentIcon; // 替换成你的图片资源 } else if (registryTypeId == 2) { row.Cells["IconColumn"].Value = Properties.Resources.ImageIcon; } // 更多类型判断... } }
方案二:给数据源添加图片列,直接绑定到图片列
另一种思路是在填充DataSet后,给DataTable添加一个存储图片的列,然后把图片列绑定到DataGridView的图片列上,这样绑定后会自动显示图片:
public void LoadDgvDocuments() { var select = "SELECT RegistryTypeId, RegistryTypeDescription FROM RegistryType"; SqlConnection c = SqlDbConnection.GetConnection(); var dataAdapter = new SqlDataAdapter(select, c); var commandBuilder = new SqlCommandBuilder(dataAdapter); var ds = new DataSet(); dataAdapter.Fill(ds); // 获取填充后的DataTable DataTable dt = ds.Tables[0]; // 添加一个类型为Image的列到DataTable dt.Columns.Add("Icon", typeof(Image)); // 遍历DataTable的行,设置图片值 foreach (DataRow row in dt.Rows) { int registryTypeId = Convert.ToInt32(row["RegistryTypeId"]); switch (registryTypeId) { case 1: row["Icon"] = Properties.Resources.PdfIcon; break; case 2: row["Icon"] = Properties.Resources.ExcelIcon; break; // 其他情况... } } // 创建图片列并绑定到DataTable的Icon字段 DataGridViewImageColumn imageColumn = new DataGridViewImageColumn(); imageColumn.DataPropertyName = "Icon"; imageColumn.HeaderText = "图标"; dataGridView1.Columns.Add(imageColumn); // 绑定数据源 dataGridView1.DataSource = dt; }
关键注意点
- 图片资源的加载:确保你用的图片资源是有效的,比如从
Properties.Resources获取的图片,或者用Image.FromFile(@"C:\path\to\image.png")加载本地图片(注意FromFile会锁定文件,用完可以用Image.FromStream避免锁定)。 - AutoGenerateColumns属性:一定要确认这个属性的设置,默认是
true,会自动生成列,很容易覆盖你手动创建的列。
内容的提问来源于stack exchange,提问作者Ahmed Faizan
相关产品推荐
相关产品推荐

