Comment afficher des images dans dataGridView?
La description.
Il est censé stocker les chemins d'images comme *.ico, *.jpg, *.pngdans la base de données.
Types de bases de données:
- SQLlite;
- Serveur SQL;
- MySQL;
J'utilise DataTable dtpour simuler le résultat d'une SELECTrequête.
Question.
- Comment afficher des images dans dataGridView?
- Quelle est la pratique la plus courante pour stocker des images dans une base de données? Stocker sous forme de chemins ou vaut-il mieux utiliser d'autres options?
- Y a-t-il des erreurs dans le code?
J'exécute l'application.
Résultat: erreur.
Erreur:
exception dans DataGridView:
System.FormatException : transtypage non valide "System.String" en "System.Drawing.Image".
Image 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;
}
}
Image-2
Mise à jour-1
Lors de la création d'une solution à ce problème, veuillez ne pas considérer les images comme "intégrées au projet".
Logique d'application:
- connectez-vous à la base de données;
- exécuter la demande;
- résultat de requête:
DataTable dt; DataTable dtcontient des chemins vers les images;
Réponses
Fondamentalement, étant donné que les images ne proviennent PAS d'une base de données mais sont incorporées dans le projet comme le montre l'image de l'explorateur de solutions, votre code devra «construire» cela en DataTableutilisant ces ressources intégrées.
Il semble que vous essayez de faire «ajouter» les images à la «colonne» des grilles. Vous souhaitez ajouter les images aux DataTableRANGÉES. Ensuite, il sera inutile d '«ajouter» la colonne «image de la grille» à la grille. La grille saura afficher les images à partir de DataTablepuisque ce sont des images «réelles».
Voici un petit exemple avec une seule colonne d'image, mais il ne devrait pas être difficile d'ajouter les autres colonnes en utilisant la même stratégie. En outre, je reçois les images qui sont intégrées en tant que ressource dans le projet, comme le montre votre image actuelle. Vous devrez changer le texte qui dit «ProjectName» avec le nom de votre projet en plus des noms de fichier image.
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;
Modifier à partir de la question OP.
L'exemple ci-dessous montre deux méthodes. Le premier est une simulation pour obtenir les données de la base de données où les images ne sont pas là mais les chemins de chaîne vers les images le sont.
Une fois que nous avons le DataTablefichier de la base de données, nous devons «ajouter» ces images à chaque ligne de l'existant DataTable. Évidemment, nous devons «ajouter» la nouvelle colonne «Image» à l'existant que DataTablenous avons obtenu de la base de données. Ensuite, parcourez chaque ligne et ajoutez l'image à la colonne d'image en fonction du chemin dans cette ligne.
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 *** si la base de données renvoie une byte[]colonne de tableau "vide" au lieu d'un Imagetype.
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();
}
}