VB .NET - DataGridView - Exibindo Imagens e texto em uma célula

 Neste artigo eu vou mostrar como podemos exibir imagens e texto em uma célula do controle DataGridView em uma aplicação Windows Forms usando a linguagem VB .NET.

O DataGridView é um controle com 1001 utilidades, flexível e poderoso se comparados com controles grids das versões anteriores do VB (lembra do DBGrid, MSFlexGrid, DataGrid, etc...)

Apesar de seus muitos recursos existem algumas tarefas que para serem efetivadas no DataGridView exigem um trabalho extra.

Vamos supor que você precisa exibir uma imagem em uma célula padrão do DataGridView, além da informação obtida a partir de um banco de dados.

Para realizar essa tarefa teremos que criar um código extra.

Complicado ??? Não !!!

Ainda bem que a linguagem VB .NET é orientada a objetos e assim podemos usar os recursos da orientação a objetos e herdar de classes que já existem sobrescrevendo métodos existentes e adaptando-os à nossa necessidade.

Neste exemplo vamos fazer o seguinte:

- criar uma classe chamada TextAndImageCell que herda da classe DataGridViewTextBoxCell. Esta classe exibe texto editável  em um controle DataGridView;      

- criar uma classe chamada TextAndImageColumn que herda da classe DataGridViewTextBoxColumn e que hospeda uma coleção de células DataGridViewTextBoxCell;

- sobrescrever o método Clone que cria uma cópia exata da célula;

- sobrescrever o método Paint;

- Definir as propriedades Image, ImageSize;

Recursos usados :

Implementando os ajustes para exibir imagem em uma célula do DataGridView

Abra o VS Express 2013 for Windows Desktop e clique em New Project;

A seguir selecione a linguagem Visual Basic e o template Windows Forms Application;

Informe o nome DataGridView_TextoImagem e clique no botão OK;

Você deve ter um local onde deve armazenar as imagens que deseja usar para exibir nas células do DataGridView.

Neste exemplo eu estou usando as imagens : Image1.jpg, Image2.jpg, Image3.jpg e Image4.jpg na pasta c:\dados.

A seguir selecione o  formulário padrão form1.vb a seguir inclua, a partir da ToolBox, o seguinte controle:

A seguir vamos definir o namespace para acessar o banco de dados Northwind.mdf

Imports System.Data.SqlClient

Logo após a declaração do formulário vamos declarar as variáveis a seguir:

Private bs As New BindingSource
Private dt As DataTable

A seguir defina o código a seguir no evento Load do formulário para obter o nome do sistema operacional usado:

 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Try
            'define a string de conexão com o banco de dados Northwind
            Dim strConn As String = "Data Source=MAC\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True"
            Dim conn As New SqlConnection(strConn)
            'define  a instrução SQL para selecionar registros da tabela Products
            Dim sql As String = "Select ProductID, ProductName, UnitPrice, UnitsInStock from Products"
            conn.Open()
            'define o dataadatper
            Dim da As New SqlDataAdapter(sql, conn)
            'cria o datatable
            dt = New DataTable
            'preeenche o datatable
            da.Fill(dt)
            'define o bindingsource com o datatable
            bs.DataSource = dt.DefaultView
            DataGridView1.DataSource = bs
            'remove a coluna ProductID
            DataGridView1.Columns.Remove("ProductID")
            'cria uma instância da classe TextAdnImagemCOlumn
            Dim dc As New TextAndImageColumn
            'define as propriedades da nova coluna
            dc.DataPropertyName = "ProductID"
            dc.HeaderText = "ID"
            'atribui uma imagem a coluna
            dc.Image = Image.FromFile("C:\Dados\Image1.jpg")
            DataGridView1.Columns.Insert(0, dc)
            ' altera a imagem para a segunda linha
            DirectCast(DataGridView1.Item(0, 1), TextAndImageCell).Image = Image.FromFile("C:\Dados\Image2.jpg")
            ' altera a imagem para a terceira linha
            DirectCast(DataGridView1.Item(0, 2), TextAndImageCell).Image = Image.FromFile("C:\Dados\Image3.jpg")
            ' altera a imagem para a quarta linha
            DirectCast(DataGridView1.Item(0, 3), TextAndImageCell).Image = Image.FromFile("C:\Dados\Image4.jpg")
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    End Sub

No evento   

  Public Class TextAndImageColumn
        Inherits DataGridViewTextBoxColumn

        Private imageValue As Image
        Private m_imageSize As Size

        Public Sub New()
            Me.CellTemplate = New TextAndImageCell
        End Sub

        Public Overloads Overrides Function Clone() As Object
            Dim c As TextAndImageColumn = TryCast(MyBase.Clone, TextAndImageColumn)
            c.imageValue = Me.imageValue
            c.m_imageSize = Me.m_imageSize
            Return c
        End Function

        Public Property Image() As Image
            Get
                Return Me.imageValue
            End Get
            Set(ByVal value As Image)
                Me.imageValue = value
                Me.m_imageSize = value.Size
                Dim inheritedPadding As Padding = Me.DefaultCellStyle.Padding
                Me.DefaultCellStyle.Padding = New Padding(ImageSize.Width, inheritedPadding.Top, inheritedPadding.Right, inheritedPadding.Bottom)
            End Set
        End Property

        Private ReadOnly Property TextAndImageCellTemplate() As TextAndImageCell
            Get
                Return TryCast(Me.CellTemplate, TextAndImageCell)
            End Get
        End Property
        Friend ReadOnly Property ImageSize() As Size
            Get
                Return m_imageSize
            End Get
        End Property
    End Class

No evento Tick do controle Timer2 temos o código exibe na ProgressBar o uso do processador: 

 Public Class TextAndImageCell
        Inherits DataGridViewTextBoxCell

        Private imageValue As Image
        Private imageSize As Size

        Public Overloads Overrides Function Clone() As Object
            Dim c As TextAndImageCell = TryCast(MyBase.Clone, TextAndImageCell)
            c.imageValue = Me.imageValue
            c.imageSize = Me.imageSize
            Return c
        End Function

        Public Property Image() As Image
            Get
                If Me.OwningColumn Is Nothing OrElse Me.OwningTextAndImageColumn Is Nothing Then
                    Return imageValue
                Else
                    If Not (Me.imageValue Is Nothing) Then
                        Return Me.imageValue
                    Else
                        Return Me.OwningTextAndImageColumn.Image
                    End If
                End If
            End Get
            Set(ByVal value As Image)
                Me.imageValue = value
                Me.imageSize = value.Size
                Dim inheritedPadding As Padding = Me.InheritedStyle.Padding
                Me.Style.Padding = New Padding(imageSize.Width, inheritedPadding.Top, inheritedPadding.Right, inheritedPadding.Bottom)
            End Set
        End Property

        Protected Overloads Overrides Sub Paint(graphics As Graphics, clipBounds As Rectangle, cellBounds As Rectangle,
                                                rowIndex As Integer, cellState As DataGridViewElementStates, value As Object, formattedValue As Object,
                                                errorText As String, cellStyle As DataGridViewCellStyle, advancedBorderStyle As DataGridViewAdvancedBorderStyle,
                                                paintParts As DataGridViewPaintParts)

            MyBase.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts)

            If Not (Me.Image Is Nothing) Then
                Dim container As System.Drawing.Drawing2D.GraphicsContainer = graphics.BeginContainer
                graphics.SetClip(cellBounds)
                graphics.DrawImageUnscaled(Me.Image, cellBounds.Location)
                graphics.EndContainer(container)
            End If

        End Sub

        Private ReadOnly Property OwningTextAndImageColumn() As TextAndImageColumn
            Get
                Return TryCast(Me.OwningColumn, TextAndImageColumn)
            End Get
        End Property

    End Class

Executando o projeto iremos obter:

Pegue o projeto completo aqui:   DataGridView_TextoImagem.zip

Ora, àquele que é poderoso para fazer tudo muito mais abundantemente além daquilo que pedimos ou pensamos, segundo o poder que em nós opera,
A esse glória na igreja, por Jesus Cristo, em todas as gerações, para todo o sempre. Amém

Efésios 3:20-21

Bons códigos...

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?


             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter
 

Referências:


José Carlos Macoratti