You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# WinForm:图片列表存Access库及轮播读取问题

问题解决指南

一、图片添加到ImageList的内存溢出问题

你已查明问题源于损坏图片,建议在代码中增加异常处理,避免单张损坏图片导致整个流程中断:

private void btnPicAdd_Click(object sender, EventArgs e)
{            
    ofdTargetPic.Filter = "Image File (*.Gif;*.jpg)|*.Gif;*.jpg";
    ofdTargetPic.Title = "Add target picture";
    ofdTargetPic.Multiselect = true;
    ofdTargetPic.FileName = string.Empty;
    DialogResult result = ofdTargetPic.ShowDialog();
    if (result == DialogResult.OK)
    {
        picTargetchoose.SizeMode = PictureBoxSizeMode.StretchImage;
        foreach (var picture in ofdTargetPic.FileNames)
        {
            try
            {
                // 用using包裹Image,避免资源泄漏
                using (Image img = Image.FromFile(picture))
                {
                    // 克隆图片后添加到ImageList,释放原文件锁
                    imgltargetpic.Images.Add(new Bitmap(img));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"图片 {picture} 加载失败:{ex.Message}");
            }
        }
    }
}

补充:用new Bitmap(img)克隆图片,还能避免Image.FromFile锁定原文件的问题。

二、Access数据库存储图片的字段类型

存储图片二进制数据时,Access数据库字段类型设置为OLE Object即可,这部分你已经配置正确。注意入库时要将图片转为二进制流存储,而非文件路径。

三、从OLE Object字段读取图片到ImageList的正确代码

你当前代码错误地使用Image.FromFile,但数据库中存储的是二进制数据而非文件路径,修正后的读取代码如下:

private void cmbTarget_SelectedIndexChanged(object sender, EventArgs e)
{
    // 清空现有ImageList,避免重复添加
    imglpicshow.Images.Clear();
    
    // 使用参数化查询,避免SQL注入风险
    string sql = "select * from targetInfo where targetName like ?";
    using (OleDbConnection con = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\Target.accdb"))
    {
        using (OleDbDataAdapter da = new OleDbDataAdapter(sql, con))
        {
            // 添加参数,处理模糊查询
            da.SelectCommand.Parameters.AddWithValue("@targetName", $"{cmbTarget.SelectedItem.ToString()}%");
            DataTable dt = new DataTable();
            da.Fill(dt);
            dgvtargetview.DataSource = dt;
            
            // 遍历所有行的图片字段,添加到ImageList
            foreach (DataRow row in dt.Rows)
            {
                if (row[3] != DBNull.Value)
                {
                    byte[] imgBytes = (byte[])row[3];
                    using (MemoryStream ms = new MemoryStream(imgBytes))
                    {
                        // 从内存流加载图片并添加到ImageList
                        imglpicshow.Images.Add(Image.FromStream(ms));
                    }
                }
            }
        }
    }
    
    // 重置轮播索引并启动Timer
    selectedpic = 0;
    if (imglpicshow.Images.Count > 0)
    {
        timerpicslide.Start();
        // 显示第一张图片
        picTargetchoose.Image = imglpicshow.Images[selectedpic];
    }
    else
    {
        timerpicslide.Stop();
        picTargetchoose.Image = null;
    }
}

关键修正点:

  • 用参数化查询替代SQL拼接,避免注入风险
  • 从DataRow中读取byte[]类型的二进制数据
  • 通过MemoryStream将二进制数据转为Image,再添加到ImageList
  • 处理DBNull情况,避免空值异常

四、轮播代码优化(可选)

原轮播代码可以简化为取模运算,逻辑更简洁:

int selectedpic = 0;
private void timerpicslide_Tick(object sender, EventArgs e)
{
    if (imglpicshow.Images.Count == 0)
    {
        timerpicslide.Stop();
        return;
    }
    picTargetchoose.Image = imglpicshow.Images[selectedpic];
    selectedpic = (selectedpic + 1) % imglpicshow.Images.Count;
}

内容的提问来源于stack exchange,提问作者grafiyas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 15:03:35