VB .NET - Trabalhando com imagens em um DataGrid


Colaboração de : André de Sousa Ferreira
 

Olá a todos;

 

Este artigo apenas vamos ilustrar como trabalhar com imagens em um DataGrid, utilizando o Visual Studio 2003.

 

Primeiramente monte um layout conforme imagem mostrado abaixo:

 

 É um layout simples não?

Não estou preocupado com o visual, mas sim com o código.

O que iremos fazer é montar um DataGrid, e em uma das colunas mostrar uma imagem, dando ao usuário, a possibilidade de atualizar a imagem, apenas com um clique do mouse.

Como você pode perceber, no nosso formulário temos apenas um Button, um DataGrid, e um ContextMenu.  Então vamos meter a mão na massa. 

Primeiramente vamos importar as classes com a qual iremos trabalhar.

Imports System.IO           'Importando a classe IO, para inclusão e atualização de imagens

Imports System.Data.OleDb   'Classe para conexão com banco de dados Access

 

No evento Load do Formulário, o código mais importante é o AddHandler ItemPicture.Click, AddressOf ClickCBO, quando eu associo um evento, ao click da imagem.

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

        intRow = 0  
       
ItemPicture = New PictureBox
       
ItemPicture.Width = 148
       
ItemPicture.Height = 124
       
ItemPicture.Cursor = System.Windows.Forms.Cursors.Arrow

        ItemPicture.Dock = DockStyle.Fill  
       
ItemPicture.SizeMode = PictureBoxSizeMode.StretchImage  

        'Associa um evento a variável do tipo PictureBox
       
' e depois cria um procedimento delegado,
       
' que faz referência ao procedimento ClickCBO.
       
' Na rotina ClickCBO, associamos ao evento click o ImageMenu

        AddHandler ItemPicture.Click, AddressOf ClickCBO  

        'Chama a rotina de atualização do Grid
       
RefereshRec()

      End Sub

Essa é a Region de rotinas, onde realizo a população do grid e a atualização da imagem. O código está comentado e você não terá dificuldades de entendê-lo.

Chamo a atenção à linha de código onde é declarada uma variável do tipo FileStream, na rotina AddNewImage. Esta rotina trabalha-se com arquivo, do tipo imagem, tanto de forma síncronas e assíncronas, para ler e escrever em determinadas operações.   

'Associa a imagem aos itens do menu suspenso

    Private Sub ClickCBO(ByVal sender As System.Object, ByVal e As System.EventArgs)
       
ItemPicture.ContextMenu = (ImageMenu)
   
End Sub

   Private Sub RetreiveImages()

        Try

            Dim MyData As Byte() = Nothing

            Dim crPosition As Integer   

            crPosition = Me.BindingContext(dt).Position   

            If blnNew = True Then ItemPicture.Image.Dispose()

            blnNew = True

            MyData = CType(ds.Tables(0).Rows(crPosition)("ItemPicture"), Byte())   

            Dim intData As New Integer

            intData = MyData.GetUpperBound(0)

            Dim fs As New FileStream("c:\tempimage.jpg", FileMode.OpenOrCreate, FileAccess.Write)

            fs.Write(MyData, 0, intData)

            fs.Close()   

            MyData = Nothing   

            ItemPicture.Image = Image.FromFile("c:\tempimage.jpg")   

        Catch ex As Exception

             MessageBox.Show(ex.Message.ToString)

        Finally

              cn.Close()

        End Try   

    End Sub   

    'Rotina de atualização de imagens
   
Private Sub updateImage()

      
Dim intItemID As Integer
      
intRow = DataGrid1.CurrentRowIndex

        Dim fsPicture As FileStream = New FileStream(strFilename, FileMode.OpenOrCreate, FileAccess.Read)   

        Dim picData() As Byte = New Byte(fsPicture.Length) {}

        fsPicture.Read(picData, 0, System.Convert.ToInt32(fsPicture.Length))

        fsPicture.Close()

        intItemID = (dt.Rows(Me.BindingContext(dt).Position)("ItemsId"))

        cmd = New OleDb.OleDbCommand("UPDATE tblPicture SET ItemPicture = @ItemPicture " & _

                                     "WHERE ItemsID = " & intItemID & "", cn)

        cmd.Parameters.Add("@ItemPicture", OleDb.OleDbType.Binary).Value = picData

          cn.Open()

        cmd.ExecuteNonQuery()

        cn.Close()   

        RefereshRec()

    End Sub

  'Rotina que alimenta o Grid, utilizando um DataTable

   Private Sub RefereshRec()   

        cmd.CommandText = "SELECT ItemsID, Item as Item, ItemPicture FROM tblPicture ORDER BY ItemsID"

        cmd.CommandType = CommandType.Text

        cmd.Connection = cn

        da.SelectCommand = cmd

        ds.Clear()

        da.Fill(ds, "tblPicture")

        dt = ds.Tables("tblPicture")   

        dgStyle.MappingName = dt.TableName

        DataGrid1.TableStyles.Add(dgStyle)

        dgStyle.PreferredRowHeight = 135

        dgStyle.PreferredColumnWidth = 205   

        colStyle = DataGrid1.TableStyles(0).GridColumnStyles

        DataGrid1.DataSource = dt

        colStyle(0).Width = 150

        colStyle(1).Width = 150

        colStyle(2).Width = 150   

        dgTable = CType(DataGrid1.TableStyles(0).GridColumnStyles(2), DataGridTextBoxColumn)

        ItemPicture.Visible = True

        ItemPicture.Focus()

        dgTable.TextBox.Controls.Add(ItemPicture)   

        ''''''''''''''''''''''''''''''''''''''''''

        Dim dgCell As DataGridCell

        dgCell = New DataGridCell(intRow, 2)

        DataGrid1.CurrentCell = dgCell

    End Sub

    'Rotina que adiciona uma nova linha ao DataGrid
  
Private Sub AddNewImage()

        Try

            Dim strItem As String

            Dim fsPicture As FileStream = New FileStream(strFilename, FileMode.OpenOrCreate, FileAccess.Read)   

            Dim picData() As Byte = New Byte(fsPicture.Length) {}

            fsPicture.Read(picData, 0, System.Convert.ToInt32(fsPicture.Length))

            fsPicture.Close()

            strItem = InputBox("Enter Item Name")

            dr = dt.NewRow

            dr("ItemsID") = (dt.Rows.Count) + 1

            dr("Item") = strItem

            dr("ItemPicture") = picData

            dt.Rows.Add(dr)

            Dim CB As New OleDbCommandBuilder(da)

            da.Update(dt)

            intRow = dt.Rows.Count

            RefereshRec()

        Catch ex As Exception 

            Throw ex

        End Try

    End Sub

Eventos de Componentes.

'Atualiza o Grid

    Private Sub btnReferesh_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnReferesh.Click

        RefereshRec()

    End Sub

 

    Private Sub DataGrid1_CurrentCellChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles DataGrid1.CurrentCellChanged

        'Mostra a 1º imagem do registro da linha atual

        RetreiveImages()

    End Sub

 

    'Chama a rotina para atualização de imagens

    Private Sub mnuImageChange_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuImageChange.Click

        Try

            ItemPicture.Image.Dispose()

            Dim dlgOpen As OpenFileDialog = New OpenFileDialog   

            If (dlgOpen.ShowDialog() = DialogResult.OK) Then

                strFilename = dlgOpen.FileName   

                ItemPicture.Image = ItemPicture.Image.FromFile(strFilename)

                updateImage()

            End If   

        Catch ex As Exception 

        End Try

    End Sub   

 

    'Evento que atualiza a imagem, dando a opção para o usuário trocar a imagem

    Private Sub mnuAddNewImage_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuAddNewImage.Click

        Try

 

            Dim dlgOpen As OpenFileDialog = New OpenFileDialog

 

            If (dlgOpen.ShowDialog() = DialogResult.OK) Then

                strFilename = dlgOpen.FileName   

                ItemPicture.Image = ItemPicture.Image.FromFile(strFilename)

                AddNewImage()

            End If

 

        Catch ex As Exception   

        End Try

    End Sub

Pronto, feito isso, rode a aplicação e veja o resultado.

 

É isso aí pessoal. Um grande abraço e até a próxima.

André de Sousa Ferreira