简体   繁体   中英

How to display images in dataGridView?

Description.
It is supposed to store paths to images like *.ico , *.jpg , *.png in the database.
Database types:

  • SQLlite;
  • SQLServer;
  • MySQL;

I am using DataTable dt to simulate the result of a SELECT query.

Question.

  1. How to display images in dataGridView?
  2. What is the most common practice for storing images in a database? Store as paths or is it better to use other options?
  3. Are there any mistakes in the code?

I am running the application.
Result: error.
Error:
Exception in DataGridView:
System.FormatException: Invalid cast "System.String" to "System.Drawing.Image".

Picture-1
在此处输入图像描述

Code

public partial class Form1 : Form
{
    DataTable dt = new DataTable();
    string pathProject = AppDomain.CurrentDomain.BaseDirectory;

    public Form1()
    {
        InitializeComponent();

        dgv.CellFormatting += Dgv_CellFormatting;
    }

    private void Dgv_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        if (dgv.Columns[e.ColumnIndex].Name == "IcoPath")
        {
            string fullpath = pathProject + e.Value.ToString();

            // e.Value = Bitmap.FromFile(fullpath);

            Image p_ImageIn = new Bitmap(fullpath);
            ImageConverter imgConverter = new ImageConverter();
            e.Value = (byte[])imgConverter.ConvertTo(p_ImageIn, typeof(Byte[]));
            e.FormattingApplied = true;
        }

    }

    private void button1_Click(object sender, EventArgs e)
    {
        dt.Columns.Add("Name", typeof(string));
        dt.Columns.Add("IcoPath", typeof(string));
        dt.Columns.Add("JpgPath", typeof(string));
        dt.Columns.Add("PngPath", typeof(string));


        // dt.Rows.Add("Name_1", @"Resources\Picture\ico\ico_1.ico");
        // dt.Rows.Add("Name_2", @"Resources\Picture\ico\ico_2.ico");
        // dt.Rows.Add("Name_3", @"Resources\Picture\ico\ico_3.ico");

        // dt.Rows.Add("Name_1", @"Resources\Picture\jpg\Jpg_1.jpg");
        // dt.Rows.Add("Name_2", @"Resources\Picture\jpg\Jpg_2.jpg");
        // dt.Rows.Add("Name_3", @"Resources\Picture\jpg\Jpg_3.jpg");

        // dt.Rows.Add("Name_1", @"\Resources\Picture\png\Png_1.png");
        // dt.Rows.Add("Name_2", @"\Resources\Picture\png\Png_2.png");
        // dt.Rows.Add("Name_3", @"\Resources\Picture\png\Png_3.png");

        dt.Rows.Add("Name_1", @"Resources\Picture\ico\ico_1.ico", @"Resources\Picture\jpg\Jpg_1.jpg", @"\Resources\Picture\png\Png_1.png");
        dt.Rows.Add("Name_2", @"Resources\Picture\ico\ico_2.ico", @"Resources\Picture\jpg\Jpg_2.jpg", @"\Resources\Picture\png\Png_2.png");
        dt.Rows.Add("Name_3", @"Resources\Picture\ico\ico_3.ico", @"Resources\Picture\jpg\Jpg_3.jpg", @"\Resources\Picture\png\Png_3.png");

        DataGridViewImageColumn icoColumn = new DataGridViewImageColumn();
        //icoColumn.HeaderText = "Image_Header";
        icoColumn.Name = "IcoPath_Name";
        icoColumn.DataPropertyName = "IcoPath";
        //// dgv.Columns.Insert(3, imageColumn);
        dgv.Columns.Add(icoColumn);

        DataGridViewImageColumn jpgColumn = new DataGridViewImageColumn();
        //icoColumn.HeaderText = "Image_Header";
        jpgColumn.Name = "JpgPath_Name";
        jpgColumn.DataPropertyName = "JpgPath";
        //// dgv.Columns.Insert(3, imageColumn);
        dgv.Columns.Add(jpgColumn);


        DataGridViewImageColumn pngColumn = new DataGridViewImageColumn();
        //icoColumn.HeaderText = "Image_Header";
        pngColumn.Name = "PngPath_Name";
        pngColumn.DataPropertyName = "PngPath";
        //// dgv.Columns.Insert(3, imageColumn);
        dgv.Columns.Add(pngColumn);


        dgv.DataSource = dt;
    }
}

Picture-2
在此处输入图像描述


Update-1

When creating a solution for this issue, please do not consider images as "embedded in the project".
Application logic:

  • connect to the database;
  • execute the request;
  • query result: DataTable dt ;
  • DataTable dt contains paths to images;

Basically, since the images are NOT coming from a DB but are embedded in the project as shown from the solution explorer picture, your code is going to have to “build” this DataTable using those embedded resources.

Is what it appears you are trying to do is “add” the pictures to the grids “column.” You want to add the images to the DataTable ROWS. Then, it will be unnecessary to “add” the “grid image” column to the grid. The grid will know how to display the images from the DataTable since they are “actual” images.

Below is a small example with only one image column, however it should not be difficult to add the other columns using the same strategy. Also, I am getting the images that are embedded as a resource in the project as your current picture shows. You will need to change the text that says “ProjectName” with the name of your project in addition to the image file names.

  DataTable dt = new DataTable();
  dt.Columns.Add("Name", typeof(string));
  dt.Columns.Add("JpgPath", typeof(Image));

  Assembly myAssembly = Assembly.GetExecutingAssembly();
  Stream myStream = myAssembly.GetManifestResourceStream("ProjectName.Resources.Picture.jpg.image1.jpg");
  Image jpg1 = new Bitmap(myStream);
  myStream = myAssembly.GetManifestResourceStream("ProjectName.Resources.Picture.jpg.image2.jpg");
  Image jpg2 = new Bitmap(myStream);
  myStream = myAssembly.GetManifestResourceStream("ProjectName.Resources.Picture.jpg.image3.jpg");
  Image jpg3 = new Bitmap(myStream);

  dt.Rows.Add("Name1", jpg1);
  dt.Rows.Add("Name2", jpg2);
  dt.Rows.Add("Name3", jpg3);

  dgv.DataSource = dt;

Edit from OP question.

The example below shows two methods. The first is a simulation of getting the data from the DB where the images are not there but the string paths to the images are.

Once we have the DataTable from the DB, we need to “add” those images to each row in the existing DataTable . Obviously, we need to “add” the new “Image” column to the existing DataTable we got from the DB. Then loop through each row and add the image to the image column based on the path in that row.

private void Form1_Load(object sender, EventArgs e) {
  DataTable DBTable = GetTableFromDB();
  AddImageColumnToDT(DBTable);
  dgv.DataSource = DBTable;
}


private DataTable GetTableFromDB() {
  DataTable dt = new DataTable();
  dt.Columns.Add("Name", typeof(string));
  dt.Columns.Add("ImagePath", typeof(string));
  dt.Rows.Add("Name1", "PathTo_Image1");
  dt.Rows.Add("Name2", "PathTo_Image2");
  dt.Rows.Add("Name3", "PathTo_Image3");
  return dt;
}

private void AddImageColumnToDT(DataTable dt) {
  dt.Columns.Add("Image", typeof(Image));
  string curPath;
  Image curImage;
  foreach (DataRow row in dt.Rows) {
    curPath = row["ImagePath"].ToString();
    curImage = Image.FromFile(curPath);
    row["Image"] = curImage;
  }
}

EDIT*** if the DB returns a "empty" byte[] array column instead of an Image type.

private DataTable GetTableFromDB2() {
  DataTable dt = new DataTable();
  dt.Columns.Add("Name", typeof(string));
  dt.Columns.Add("ImagePath", typeof(string));
  dt.Columns.Add("Image", typeof(byte[]));
  dt.Rows.Add("Name1", "PathTo_Image1");
  dt.Rows.Add("Name2", "PathTo_Image2");
  dt.Rows.Add("Name3", "PathTo_Image3");
  return dt;
}

private void AddImageColumnToDT2(DataTable dt) {
  //dt.Columns.Add("Image", typeof(byte[]));
  string curPath;
  Image curImage;
  byte[] curByteArray;
  foreach (DataRow row in dt.Rows) {
    curPath = row["ImagePath"].ToString();
    curImage = Image.FromFile(curPath);
    curByteArray = imageToByteArray(curImage);
    row["Image"] = curByteArray;
  }
}

public byte[] imageToByteArray(Image imageIn) {
  using (MemoryStream ms = new MemoryStream()) {
    imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
    return ms.ToArray();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM