Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
160 views
in Technique[技术] by (71.8m points)

c# - 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
enter image description here

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", @"ResourcesPictureicoico_1.ico");
        // dt.Rows.Add("Name_2", @"ResourcesPictureicoico_2.ico");
        // dt.Rows.Add("Name_3", @"ResourcesPictureicoico_3.ico");

        // dt.Rows.Add("Name_1", @"ResourcesPicturejpgJpg_1.jpg");
        // dt.Rows.Add("Name_2", @"ResourcesPicturejpgJpg_2.jpg");
        // dt.Rows.Add("Name_3", @"ResourcesPicturejpgJpg_3.jpg");

        // dt.Rows.Add("Name_1", @"ResourcesPicturepngPng_1.png");
        // dt.Rows.Add("Name_2", @"ResourcesPicturepngPng_2.png");
        // dt.Rows.Add("Name_3", @"ResourcesPicturepngPng_3.png");

        dt.Rows.Add("Name_1", @"ResourcesPictureicoico_1.ico", @"ResourcesPicturejpgJpg_1.jpg", @"ResourcesPicturepngPng_1.png");
        dt.Rows.Add("Name_2", @"ResourcesPictureicoico_2.ico", @"ResourcesPicturejpgJpg_2.jpg", @"ResourcesPicturepngPng_2.png");
        dt.Rows.Add("Name_3", @"ResourcesPictureicoico_3.ico", @"ResourcesPicturejpgJpg_3.jpg", @"ResourcesPicturepngPng_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
enter image description here


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;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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();
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...