Link to home
Start Free TrialLog in
Avatar of Keyboard
Keyboard

asked on

Displaying images in datagrid - Windows Forms (VB.Net)

A datagrid on a Windows Forms displays the rows from a single table. One of the columns in the table contains the full path of images. When displaying the rows, I want to display the image, rather the full path, in the datagrid. How do I do this?

Essentially, what I am trying to ask is, 'How do we host image controls, in a datagrid'. I am looking for VB.Net assistance and not C#. Also, I have seen code that does this in Web Forms (ASP.Net) using TemplateColumns. And that is not what I am looking at either.

thanks. Help appreciated.

--.Net Newbie
SOLUTION
Avatar of pillbug22
pillbug22

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of Ralf Klatt
Ralf Klatt
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Keyboard
Keyboard

ASKER

pillbug22: That was a good example. Alas, the author uses an arraylist to store all the images. I don't want to store the images in a separate collection.

Raisor:
Uh...it looks like ASP.net. I don't have the expertise to convert the code to VB.Net (Windows Forms) yet. Well, can you give the Windows Forms code?

So guys, help me out....
I haven't looked at his code, but I don't see why you couldn't use the images from your own collection instead of an array.

Arrays, datasets, datareaders, XML, they all hold the same thing, just in different ways.
Hi,

@keyboard ... ups!!! ... You're right ... my mistake!!!

@pillbug22 ... do you have to provide a solution that fits with keyboards' request ... or shall I take care?


Best regards, Raisor

Well, the example I gave used an Array to store the images (which he didn't want), so I'm working through the code to use the returned SQL row instead.  Be my guest to help out here!

Here's the important stuff I believe:





    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

        'create a datatable
        Dim dt As New DataTable("MyTable")

        dt.Columns.Add(New DataColumn("Col0"))
        dt.Columns.Add(New DataColumn("Images", GetType(Integer)))

        Dim r As New Random()
        Dim i As Integer

        For i = 0 To nRows - 1
            Dim dr As DataRow = dt.NewRow()
            dr(0) = String.Format("row{0}", i)
            dr(1) = r.Next(4)
            dt.Rows.Add(dr)
        Next

        'store bitmaps in an arraylist
        bitMaps = New ArrayList()
        Dim strm As System.IO.Stream = [GetType]().Assembly.GetManifestResourceStream("ImageCellInDataGrid.Blue hills.jpg")
        bitMaps.Add(New Bitmap(strm))
        strm = [GetType]().Assembly.GetManifestResourceStream("ImageCellInDataGrid.Sunset.jpg")
        bitMaps.Add(New Bitmap(strm))
        strm = [GetType]().Assembly.GetManifestResourceStream("ImageCellInDataGrid.Water lilies.jpg")
        bitMaps.Add(New Bitmap(strm))
        strm = [GetType]().Assembly.GetManifestResourceStream("ImageCellInDataGrid.Winter.jpg")
        bitMaps.Add(New Bitmap(strm))


        'create an imagelist
        '                  ImageList images = new ImageList();
        '                  System.IO.Stream strm = GetType().Assembly.GetManifestResourceStream("ImageCellInDataGrid.Blue hills.jpg");
        '                  images.Images.Add(new Bitmap(strm));
        '                  strm = GetType().Assembly.GetManifestResourceStream("ImageCellInDataGrid.Sunset.jpg");
        '                  images.Images.Add(new Bitmap(strm));
        '                  strm = GetType().Assembly.GetManifestResourceStream("ImageCellInDataGrid.Water lilies.jpg");
        '                  images.Images.Add(new Bitmap(strm));
        '                  strm = GetType().Assembly.GetManifestResourceStream("ImageCellInDataGrid.Winter.jpg");
        '                  images.Images.Add(new Bitmap(strm));
        '                  
        '                  images.Images.Add(SystemIcons.Warning.ToBitmap());
        '                  images.Images.Add(SystemIcons.Application.ToBitmap());
        '                  images.Images.Add(SystemIcons.Asterisk.ToBitmap());
        '                  images.Images.Add(SystemIcons.Error.ToBitmap());
        '                  images.Images.Add(SystemIcons.Exclamation.ToBitmap());
        '                  images.Images.Add(SystemIcons.Hand.ToBitmap());
        Dim tableStyle As New DataGridTableStyle()
        tableStyle.MappingName = "MyTable"

        Dim tbc As New DataGridTextBoxColumn()
        tbc.MappingName = "Col0"
        tbc.HeaderText = "Column 1"
        tbc.Width = 50
        tableStyle.GridColumnStyles.Add(tbc)

        Dim width As Integer = Me.dataGrid1.ClientSize.Width - tbc.Width - Me.dataGrid1.RowHeaderWidth - 4
        Dim tbc1 As New DataGridImageCell()
        tbc1.MappingName = "Images"
        tbc1.HeaderText = "Images"
        tbc1.theImages = bitMaps
        tbc1.Width = width
        tableStyle.GridColumnStyles.Add(tbc1)

        Me.dataGrid1.TableStyles.Add(tableStyle)
        Me.dataGrid1.DataSource = dt
        dt.DefaultView.AllowNew = False

        Dim rect As Rectangle = Me.dataGrid1.GetCellBounds(0, 0)
        topPos = rect.Top
        Dim height As Integer = (Me.dataGrid1.ClientSize.Height - topPos - nRows) / nRows
        tableStyle.PreferredRowHeight = height
        Me.dataGrid1.DataSource = Nothing
        Me.dataGrid1.DataSource = dt
    End Sub 'Form1_Load









Imports System
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Data
Imports System.Collections


'/ <summary>
'/ Summary description for DataGridImageCell.
'/ </summary>

Public Class DataGridImageCell
   Inherits DataGridTextBoxColumn
   Private theImages1 As ArrayList
   
   Public Sub New()
   End Sub 'New
   
   
   Public Property theImages() As ArrayList
      Get
         Return theImages1
      End Get
      Set
         theImages1 = value
      End Set
   End Property
   
    Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics, ByVal bounds As System.Drawing.Rectangle, ByVal [source] As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal backBrush As System.Drawing.Brush, ByVal foreBrush As System.Drawing.Brush, ByVal alignToRight As Boolean)
        Dim o As Object = Me.GetColumnValueAtRow([source], rowNum)
        If Not (o Is Nothing) Then
            Dim i As Integer = Fix(o)
            g.FillRectangle(backBrush, bounds)

            Dim bmp As Bitmap = CType(theImages(i), Bitmap)

            'GridImageCellDrawOption cellDrawOption = GridImageCellDrawOption.NoResize;
            'GridImageCellDrawOption cellDrawOption = GridImageCellDrawOption.FitProportionally;
            Dim cellDrawOption As GridImageCellDrawOption = GridImageCellDrawOption.FitToCell


            Dim gu As System.Drawing.GraphicsUnit = System.Drawing.GraphicsUnit.Point

            Dim srcRect As RectangleF = bmp.GetBounds(gu)
            Dim destRect As Rectangle = Rectangle.Empty

            Dim saveRegion As [Region] = g.Clip

            Select Case cellDrawOption
                Case GridImageCellDrawOption.FitToCell
                    destRect = bounds
                Case GridImageCellDrawOption.NoResize
                    destRect = New Rectangle(bounds.X, bounds.Y, Fix(srcRect.Width), Fix(srcRect.Height))
                    g.Clip = New [Region](bounds)
                Case GridImageCellDrawOption.FitProportionally
                    If (True) Then
                        Dim srcRatio As Single = srcRect.Width / srcRect.Height
                        Dim tarRatio As Single = System.Convert.ToSingle(bounds.Width) / bounds.Height
                        destRect = bounds
                        If tarRatio < srcRatio Then
                            destRect.Height = Fix(destRect.Width * srcRatio)
                        Else
                            destRect.Width = Fix(destRect.Height * srcRatio)
                        End If
                    End If

                Case Else
            End Select

            If Not destRect.IsEmpty Then
                'g.DrawImage(bmp, destRect, srcRect, gu)
                Dim destRectF As New RectangleF(destRect.X, destRect.Y, destRect.Width, destRect.Height)
                Dim srcRectF As New RectangleF(srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height)

                g.DrawImage(bmp, destRectF, srcRectF, gu)
            End If
            g.Clip = saveRegion
        End If
    End Sub 'Paint


    Protected Overloads Overrides Sub Edit(ByVal [source] As System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, ByVal instantText As String, ByVal cellIsVisible As Boolean)
        'overriden to avoid editing
    End Sub 'Edit



    Public Enum GridImageCellDrawOption
        FitToCell = 0
        NoResize = 1
        FitProportionally = 2
    End Enum 'GridImageCellDrawOption

End Class 'DataGridImageCell
Hi,

@pillbug22 ... After looking at your code I'm not having any problem to state that I'm sure your example is a very good one!!!

@keyboaord ... I was looking a little arround in old and current projects ---> "my source code collection ;-))" <--- and unforunately I've found only an "Amazon Appplication" -> that app is working with amazon product catalogues and with my personal developer token from amazon -> on any query the results are presented in a datagrid ... with images of products -> but!!! ... to extract the important source code would be more work than starting a small app from the scratch ... as you've stated you're newbie to vb.net and that's why I think that this article here can fit perfectly to your needs ---> http://www.vbdotnetheaven.com/Code/Jun2003/2078.asp <--- It will show you a lot of how to work with a datagrid in vb.net and it will give you an everlasting experience in working/programming with all possible controls that can be used in a datagrid (even generated from a database!) ...


Best regards, Raisor
thanks pilbug22 and raisor for your continued support.

pilbug22: the image is actually painted in the paint methods. though been working with VB6 for ages, never even once, did I need to use the paint, draw, graphics...so that side of the programming world is new to me. essentially the image needs to be drawn in the grid cell, right? the code uses the array, i will attempt to decipher the code. but can we do something the way I want....
....read a sql table, get a bunch of rows in a dataset...use this dataset to bind the datagrid. when the rows are being loaded, load the image from the file path......