locked
May i ask a code about picture box auto fit RRS feed

  • Question

  • i try to wring a code is auto fit textbox. the problem i face is, i non image Unable to cast object of type 'System.DBNull' to type 'System.Byte[]

    Below is my code                 

    Private Sub AutoFitTextbox()

    Private Sub autofit()
            Dim command As New OleDbCommand("SELECT * FROM Table1 WHERE F3 = @F3", cnn)
            If TextBox4.Text IsNot "" Then
                command.Parameters.Add("@F3", OleDbType.VarChar).Value = TextBox4.Text
                Dim adapater As New OleDbDataAdapter(command)
                Dim table As New DataTable

                adapater.Fill(table)

                TextBox1.Text = ""
                TextBox2.Text = ""
                TextBox3.Text = ""

                If table.Rows.Count() > 0 And table.Rows.Count() < 2 Then
                    '  If table.Rows(0)("picture") = Empty Then
                    ID.Text = table.Rows(0)(0).ToString
                    TextBox1.Text = table.Rows(0)("F1").ToString
                    TextBox2.Text = table.Rows(0)("F2").ToString
                    TextBox3.Text = table.Rows(0)("F3").ToString

                    Dim bytes As [Byte]() = CType(table.Rows(0)("Picture"), Byte())
                    Dim ms As New MemoryStream(bytes)
                    PictureBox1.Image = Image.FromStream(ms)

                    Dim bytes1 As [Byte]() = CType(table.Rows(0)("Picture1"), Byte())
                    Dim ms1 As New MemoryStream(bytes1)
                    PictureBox2.Image = Image.FromStream(ms1)

    may i ask my datagridview image column is empty how to display data only 

    can someone give me advise.

    • Edited by christing Saturday, June 27, 2020 1:49 AM
    Friday, June 26, 2020 3:46 PM

Answers

  • Usually if is no image for a DataRow we get

    To avoid this. Create a blank image

    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim blankImage As New Bitmap(125, 125)
    

    Have a function to convert the image to a byte array

    Public Function ImageToByteArray(pImage As Image) As Byte()
        Dim ms As New MemoryStream()
        pImage.Save(ms, Imaging.ImageFormat.Png)
        Return ms.ToArray()
    End Function

    Test for no image

    If table.Rows(0).Field(Of Byte())("picture") Is Nothing Then
        table.Rows(0).SetField(Of Byte())("picture", ImageToByteArray(blankImage))
    End If

    We now get

    All of the above is a modified code sample I did for a post earlier this week were images were read from disk rather than a database table which doesn't matter were the data comes from as the DataTable contents is the only thing that matters, same will work if the data came from a database.

    Note CellFormatting event, this handles the new row not to show a X for a empty image.

    Imports System.IO
    ''' <summary>
    ''' In this case DataGridView columns are created
    ''' in the designer and DataPropertyName is set there too
    ''' </summary>
    Public Class Form2
        Private newRowImage As Bitmap
        Public Function ImageToByteArray(pImage As Image) As Byte()
            Dim ms As New MemoryStream()
            pImage.Save(ms, Imaging.ImageFormat.Png)
            Return ms.ToArray()
        End Function
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim blankImage As New Bitmap(125, 125)
    
            newRowImage = blankImage
    
            DataGridView1.AutoGenerateColumns = False
    
            Dim files = Directory.GetFiles(
                AppDomain.CurrentDomain.BaseDirectory,
                "*.png")
    
            Dim table As New DataTable()
            table.Columns.Add("ImageColumn", GetType(Byte()))
            table.Columns.Add("NameColumn", GetType(String))
    
            For Each file As String In files
                Dim img As Image = Image.FromFile(file)
    
                table.Rows.Add(New Object() {ImageToByteArray(img), Path.GetFileName(file)})
    
                img.Dispose()
            Next
    
            '
            ' Simulate no image
            '
            table.Rows(0).SetField(Of Byte())("ImageColumn", Nothing)
            '
            ' Test for no image, if none present a blank image.
            '
            If table.Rows(0).Field(Of Byte())("ImageColumn") Is Nothing Then
                table.Rows(0).SetField(Of Byte())("ImageColumn", ImageToByteArray(blankImage))
            End If
    
            DataGridView1.RowTemplate.Height = 125
    
            DataGridView1.DataSource = table
            DataGridView1.Columns("ImageColumn").Width = 125
    
            CType(DataGridView1.Columns("ImageColumn"), DataGridViewImageColumn).
                ImageLayout = DataGridViewImageCellLayout.Normal
    
        End Sub
    
    
        Private Sub DataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) _
            Handles DataGridView1.CellFormatting
    
            If DataGridView1.Rows(e.RowIndex).IsNewRow AndAlso e.ColumnIndex = 0 Then
                e.Value = newRowImage
            End If
    
        End Sub
    End Class
    
    

    To discard a row with no image

    Imports System.IO
    ''' <summary>
    ''' In this case DataGridView columns are created
    ''' in the designer and DataPropertyName is set there too
    ''' </summary>
    Public Class Form2
        Private newRowImage As Bitmap
        Public Function ImageToByteArray(pImage As Image) As Byte()
            Dim ms As New MemoryStream()
            pImage.Save(ms, Imaging.ImageFormat.Png)
            Return ms.ToArray()
        End Function
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Dim blankImage As New Bitmap(125, 125)
    
            newRowImage = blankImage
    
            DataGridView1.AutoGenerateColumns = False
    
            Dim files = Directory.GetFiles(
                AppDomain.CurrentDomain.BaseDirectory,
                "*.png")
    
            Dim table As New DataTable()
            table.Columns.Add("ImageColumn", GetType(Byte()))
            table.Columns.Add("NameColumn", GetType(String))
    
            For Each file As String In files
                Dim img As Image = Image.FromFile(file)
    
                table.Rows.Add(New Object() {ImageToByteArray(img), Path.GetFileName(file)})
    
                img.Dispose()
            Next
    
    
            table.Rows(0).SetField(Of Byte())("ImageColumn", Nothing)
    
    
            Dim noEmptyImages As DataRow() = table.AsEnumerable().
                    Where(Function(row) row.Field(Of Byte())("ImageColumn") IsNot Nothing).
                    ToArray()
    
            Dim tableClone = table.Clone()
            For Each row As DataRow In noEmptyImages
                tableClone.ImportRow(row)
            Next
    
    
            DataGridView1.RowTemplate.Height = 125
    
            DataGridView1.DataSource = tableClone
            DataGridView1.Columns("ImageColumn").Width = 125
    
            CType(DataGridView1.Columns("ImageColumn"), DataGridViewImageColumn).
                ImageLayout = DataGridViewImageCellLayout.Normal
    
        End Sub
    
    
        Private Sub DataGridView1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) _
            Handles DataGridView1.CellFormatting
    
            If DataGridView1.Rows(e.RowIndex).IsNewRow AndAlso e.ColumnIndex = 0 Then
                e.Value = newRowImage
            End If
    
        End Sub
    End Class
    
    


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by christing Monday, June 29, 2020 1:29 AM
    Saturday, June 27, 2020 10:31 AM