 VB .NET - Manipulando o DataGridView
 VB .NET - Manipulando o DataGridView
|  | 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...)  | 
Embora não seja complicado de usar como toda novidade desperta curiosidade e dúvidas, e, por este motivo este artigo procurar mostrar as maneiras mais comuns e úteis de usar o controle DataGridView.
Para começar você vai ter que ter instalado os seguintes recursos:
O primeiro passo e abrir o VB 2005 Express e criar uma aplicação Windows Forms via opção File->New Project com o nome de datagridViewTotal
|  | 
Aqui é o ponto de partida para a nossa jornada, vamos lá...
Usando DataGridView com Arrays
Vamos definir um array chamado vetor com dois elementos e vincular o array ao DataGridView usando a propriedade DataSource:
| Private
        Sub Form1_Load(ByVal sender As System.Object, ByVal e As
        System.EventArgs) Handles MyBase.Load '========================================== 'outras maneiras de declarar e iniciar um array '(a) 'Dim vetor(2) As String 'vetor(0) = "Super CD VB 40,00" 'vetor(1) = "Super DVD.NET 50,00" '(b) 'Dim vetor() As String 'vetor = New String() {"Super CD VB 40,00", "Super DVD .NET 50,00"} '============================================= Dim vetor() As String = {"Super CD VB 40,00", "Super DVD .NET 50,00"} DataGridView1.DataSource = vetor End Sub |  | 
Opa ! mas o que aconteceu ??? O resultado não é o esperado. Por que ?
Você esperava que os elementos do array fossem exibidos mas somente o tamanho de cada elemento foi exibido.
O motivo deste comportamento é que o DataGridView procura pela primeira propriedade pública do objeto ao qual esta vinculado e a primeira propriedade pública de um array de strings é o tamanho de cada elemento contido no array.
Para fazer da maneira correta devemos envolver o array de string em uma classe que exponha propriedades públicas que retornem o conteúdo de cada um dos elementos que desejamos exibir.
Podemos fazer isso criando uma classe e definindo um construtor e uma propriedade pública para ter acesso ao valor de cada elemento do vetor:
No menu Project -> Add Class selecione o template Class e informe o nome vetor.vb para o nome da classe a seguir inclua o seguinte código na classe:
|  | 
Voltando ao formulário form1.vb e alterando o código para usar a classe criada temos:
| Private Sub
        Form1_Load(ByVal sender As System.Object, ByVal e As
        System.EventArgs) Handles MyBase.Load 'Dim vetor() As String = {"Super CD VB 40,00", "Super DVD .NET 50,00"} '========================================== 'outras maneiras de declarar e iniciar um array '(a) 'Dim vetor(2) As String 'vetor(0) = "Super CD VB 40,00" 'vetor(1) = "Super DVD.NET 50,00" '(b) 'Dim vetor() As String 'vetor = New String() {"Super CD VB 40,00", "Super DVD .NET 50,00"} '============================================= Dim valores() As Vetor = {New Vetor("Super CD VB 40,00"), New Vetor("Super DVD .NET 50,00")} DataGridView1.DataSource = valores End Sub |  | 
Da mesma forma podemos vincular o controle DataGridView a um objeto mais complexo.
Usando DataGridView com DataSets Tipados
Um uso muito comum do controle DataGridView é a vinculação a uma tabela de um banco de dados. Podemos efetuar esta tarefa usando um DataSet tipado.
Vamos incluir um dataset tipado ao projeto clicando sobre o nome do projeto com o botão direito do mouse e seleciona a opção Add New Item. Na janela selecione o template DataSet e clique Add;
Habilite o DataBase Explorer no menu View e localize o banco de dados Northwind.mdf , expanda o objeto Tables e em seguida arraste e solte a tabela Customers no descrito DataSet1.xsd conforme a figura abaixo:
|  | 
No próximo passo vamos vincular o dataset ao DataGridView e podemos fazer isto das seguintes formas:
1- Vincular o DataGridView diretamente ao adapter da tabela Customers:
Inclua o projeto a seguinte declaração :
Imports dataGridViewTotal.DataSet1TableAdapters
A seguir inclua um botão de comando no formulário e inclua o código abaixo no evento Click do botão:
| Private Sub Button1_Click(ByVal sender
        As System.Object, ByVal e As System.EventArgs) Handles
        Button1.Click 'cria uma instância da TableAdapter Dim da As New CustomersTableAdapter 'vincula o TableAdapter ao DataGridView DataGridView1.DataSource = da.GetData End Sub | 
Executando o projeto temos:
|  | 
2- Vinculando o DataGridView a um BindginSource
Para este exemplo você deve criar um TableAdapter para a tabela Customers. Para fazer isso inclua um novo DataSet no projeto e arraste a partir da janela DataBase Explorer a tabela Customers do banco de dados Northwind.mdb.
A seguir Inclua no projeto a seguinte declaração (se ainda não o fez) :
Imports dataGridViewTotal.DataSet1TableAdapters
Agora insira um novo botão de comando e no evento Click do botão insira o código:
| Private Sub Button2_Click(ByVal sender As
        System.Object, ByVal e As System.EventArgs) Handles
        Button2.Click 'cria uma instância da TableAdapter Dim da As New CustomersTableAdapter 'cria uma instância de um BindingSource Dim bindsrc As New BindingSource 'define a fonte de dados para o bindingsource e obtém os dados do método GetData do TableAdapter bindsrc.DataSource = da.GetData 'vincula o BindingSource ao DataGridView DataGridView1.DataSource = bindsrc End Sub | 
Usando o DataGridView com DataSets não tipados
Você também pode definir o dataset via código vinculando em seguida o componente ao DataGridView.
Primeiro temos que criar e preencher um dataset para em seguida atribuir à propriedade DataSource do DataGridView o dataset gerado.
No código estou atribuindo à propriedade DataMember a tabela gerada no dataset. Uma outra maneira de obter o mesmo resultado seria atribuir diretamente a propriedade DataSource a tabela gerada que no caso seria a primeira tabela (pois só temos uma) : ds.tables(0). Neste caso não necessitaríamos de definir o Datamember.
| Private
        Sub 
        Button1_Click(ByVal 
        sender As 
        System.Object, ByVal 
        e As 
        System.EventArgs) Handles 
        Button1.Click 'define a string de conexaoDim connStr As String = "Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True" 'define a instrução sql Dim sql As String = "SELECT * FROM Customers" 'define os objetos connecton, command e dataadapter Dim conn As SqlConnection = New SqlConnection(connStr) Dim comm As SqlCommand = New SqlCommand(sql, conn) Dim dataadapter As SqlDataAdapter = New SqlDataAdapter(comm) 
         
         '---abre a conexao--- conn.Open() '---preenche o dataset--- dataadapter.Fill(ds, "Clientes") '---fecha a conexao--- conn.Close() '---vincula o dataset ao DataGridView--- DataGridView1.DataSource = ds 'ou ds.tables(0) '---define a tabela a ser exibida--- DataGridView1.DataMember = "Clientes"Catch ex As Exception 
 End TryEnd Sub | 
| 
         | 
Obtendo o valor da célula selecionada e Atribuindo a célula atual
Para obter o valor da célula clicada pelo usuário em um DataGridView usamos o evento CellEnter:
| Private
    Sub 
    DataGridView1_CellEnter(ByVal 
    sender As
    Object,
    ByVal e
    As 
    System.Windows.Forms.DataGridViewCellEventArgs)
    Handles 
    DataGridView1.CellEnter 
    '---Quando o usuário 
    clicar no controle , exibe o conteudo da célula End Sub | 
Neste código estamos obtendo o valor da célula pelo índice da linha (e.RowIndex) e da coluna (e.ColumnIndex).
Se desejar obter valor da primeira coluna quando o usuário selecionar uma linha o código ficaria assim :
| Private
    Sub 
    DataGridView1_CellEnter(ByVal 
    sender As
    Object,
    ByVal e
    As 
    System.Windows.Forms.DataGridViewCellEventArgs)
    Handles 
    DataGridView1.CellEnter 
    '---Quando o usuário 
    clicar no controle , exibe o conteudo da célula referente a primeira coluna 
    (Column=0) End Sub | 
|  | 
Para atribuir a célula atual via código podemos atribuir um valor a propriedade CurrentCell do DataGridView . No código abaixo estou atribuindo a célula atual como sendo a primeira linha e a segunda coluna ( row=0 e column=1)
| Private Sub 
    setCurrentCellButton_Click(ByVal sender
    As Object, 
    ByVal e As 
    System.EventArgs) Handles 
    setCurrentCellButton.Click ' Define a célula atual para a célula na coluna 1 e linha 0 Me.dataGridView1.CurrentCell = Me.dataGridView1(1, 0) End Sub | 
Validando a entrada de dados em uma célula
Podemos usar o evento CellValidating para verificar se a entrada de um usuário quando da edição dos dados de uma célula estiver ocorrendo é valida ou não.
No exemplo acima iremos efetuar a validação da coluna CompanyName para isso devemos implementar o tratamento dos eventos CellValidating e CellEndEdits.
O evento CellValidating ocorre quando a célula perde o foco de entrada habilitando a validação do seu conteúdo.
O evento CellEndEdits ocorre quando o modo de edição é encerrado para a atual célula selecionada.
No evento CellValidating é onde você determina se o valor de uma célula para um determinada coluna é válida. Se a validação da célula falha defina a propriedade Cancel da classe System.Windows.Forms.DataGridViewCellValidatingEventArgs para true. Isto faz com que o controle DataGridView não permita que o cursor deixe a célula.
Definindo a propriedade ErrorText na linha para exibir uma mensagem para o usuário exibe um ícone de erro com uma dica que contém o texto para o erro.
No evento CellEndEdit defina a propriedade ErrorText na linha para uma string vazia. Este evento ocorre somente quando a célula existe no modo edit o qual não pode ocorrer se a validação falhar.
No exemplo vamos verificar se a coluna CompanyName esta vazia para a entrada do usuário:
| PrivateSub dataGridView1_CellValidating(ByVal sender As Object, ByVal e As DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating 
 DataGridView1.Rows(e.RowIndex).ErrorText = "O nome da Companhia não pode ser vazio." e.Cancel = True End IfEnd If End Sub Private Sub dataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit ' Limpa o erro da linha no caso do usuário pressionar ESC DataGridView1.Rows(e.RowIndex).ErrorText = String.Empty End Sub 
 | 
| 
     | 
Tratando ocorrências de erros em um DataGridView
Podemos efetuar o tratamento de erros para o controle DataGridView usando o evento DataError o qual é disparado quando a fonte de dados detecta uma violação de restrição ou quebra de regra de negócio.
A seguir temos um exemplo que quando ocorrer um valor para o campo CustomerID duplicado em uma nova linha ou linha sendo editada o evento DataError irá ocorrer e será tratado pela exibição de uma mensagem que descreve o erro.
| Private
    Sub 
    dataGridView1_DataError(ByVal 
    sender As
    Object,
    ByVal e
    As 
    DataGridViewDataErrorEventArgs)  
    Handles 
    DataGridView1.DataError 
    ' Se a fonte de dados levanta uma exceção 
    quando uma célula esta comitda exibe um erro. | 
Exibindo imagens em células de um DataGridView
Podemos exibir uma figura ou um gráfico em uma linha de dados. Para exibir imagens em um controle DataGridView não há muito segredo pois ele trata nativamente qualquer imagem suportada pela classe Image bem como o ormato de imagem OLE usado por alguns banco de dados.
Se a fonte de dados do controle DataGridView possuir uma coluna com imagens , elas serão exibida automaticamente exibidas no controle DataGridView.
Filtrando e ordenando colunas via código
Para filtrar os dados exibidos em um DataGridView podemos usar um objeto DataView. A seguir temos um exemplo onde estamos filtrando os dados para o código do cliente iniciado pela letra B:
Nota: Para este exemplo você deve criar um TableAdapter para a tabela Customers. Para fazer isso inclua um novo DataSet no projeto e arraste a partir da janela DataBase Explorer a tabela Customers do banco de dados Northwind.mdb.
Você deverá declarar os seguintes namespaces no projeto para que o código abaixo funcione:
Imports
System.Data.sqlclient| PrivateSub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click 
 
     
     .AllowNew = False .AllowDelete = True .Sort = "ContactTitle ASC, Address ASC" .RowFilter = "CustomerID LIKE 'B*'"End With ' atribui o dataview ao datagridview DataGridView1.DataSource = dv End Sub | 
O resultado da execução deste código será:|  | 
|  | 
O dataView é obtido a partir do adapter chamando o método 
getData que retorna um DataTable preenchido conforme a consulta 
SQL definida.
No 
código acima o objeto DataView permite aos usuário incluir novas linhas , via 
propriedade AllowNew no controle DataGridView e também excluir  linhas , via 
propriedade AllowDelete.
Podemos ainda ordenar as 
linhas especificando o campo e a ordem correspondente que será aplicada usando a 
propriedade Sort. (ASC ordem ascendente DESC ordem descendente)
O filtro é feito pela expressão SQL 
usando a expressão LIKE via propriedade RowFilter.
Uma outra maneira de ordenar colunas 
é usar o método Sort do próprio controle DataGridView:
| Private
    Sub 
    Button3_Click(ByVal 
    sender As 
    System.Object, ByVal 
    e As 
    System.EventArgs) Handles 
    Button3.Click DataGridView1.Sort(DataGridView1.Columns(0), System.ComponentModel.ListSortDirection.Descending) End Sub | 
O código esta ordenando pela primeira coluna do componente (Columns(0)) usando a ordem descendente.
Definindo um texto em ToolTips em células individuais
De forma geral usamos o recurso ToolTips para exibir valores em células do DataGridView que são muito pequenas para exibir todo o conteúdo. Podemos reescrever este comportamento de forma a definir textos para ToolTips para células individuais. Isto é útil para exibir informação adicional sobre a célula ou para fornecer ao usuário uma descrição mais detalhada sobre o conteúdo da célula.
Para isto eu vou usar o o evento CellFormatting que ocorre quando o conteúdo de uma célula precisa ser formatado para exibição.
A tabela Customers não possui um campo muito adequado para um exemplo mais convincente ,vou usar portanto o campo City de e escolher algumas cidades de forma que exibam o nome do pais a qual pertençam. O código é o seguinte:
| 'Define o texto da propriedade ToolTip para células da coluna especificada , no caso a coluna: CitySub dataGridView1_CellFormatting(ByVal sender As Object, ByVal e As DataGridViewCellFormattingEventArgs) _ Handles DataGridView1.CellFormatting 
 If e.ColumnIndex = Me.DataGridView1.Columns("City").Index AndAlso (e.Value IsNot Nothing) Then With Me.DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex) If e.Value.Equals("London") Then .ToolTipText = "< Inglaterra >" ElseIf e.Value.Equals("Sao Paulo") Then .ToolTipText = "< Brasil > " ElseIf e.Value.Equals("Madrid") Then .ToolTipText = "< Espanha >" ElseIf e.Value.Equals("Buenos Aires") Then .ToolTipText = "< Argentina >" End If End WithEnd If End Sub | 
O resultado pode ser visto na figura abaixo:
|  | 
Exibindo uma combobox em uma célula
Você pode exibir uma combobox em uma célula de forma a permitir que o usuário selecione valores determinados de uma lista existente. Neste caso você precisa incluir uma ComboBox na célula da coluna desejada. O código abaixo faz exatamente isto usando o controle BindingSource:
| Private
    Sub Form2_Load(ByVal 
    sender As 
    System.Object, ByVal 
    e As 
    System.EventArgs) Handles MyBase.Load 
 '---inclui colunas no controle DataGridView--- DataGridView1.Columns.Add("ID", "Codigo") DataGridView1.Columns.Add("Nome", "Nome Aluno") 
 '---define um controle bindingsource---Dim bindingsource As New BindingSource 
 '---inclui itens no controle--- bindingsource.Add("Matemática") bindingsource.Add("Português") bindingsource.Add("História") 
 '---cria uma coluna do tipo combobox---Dim comboBoxCol As New DataGridViewComboBoxColumn 
 '---define o cabecalho (header) --- comboBoxCol.HeaderText = "Disciplinas" '---vincula os dados--- comboBoxCol.DataSource = bindingsource 
 '---Inclui a coluna combobox ao DataGridView--- DataGridView1.Columns.Add(comboBoxCol) End Sub | 
|  | 
Se você não quiser usar um controle BindingSource pode incluir os itens diretamente no controle DataGridViewComboBoxColumn :
| Private
    Sub Form2_Load(ByVal 
    sender As 
    System.Object, ByVal 
    e As 
    System.EventArgs) Handles MyBase.Load 
 '---inclui colunas no controle DataGridView--- DataGridView1.Columns.Add("ID", "Codigo") DataGridView1.Columns.Add("Nome", "Nome Aluno") 
 '---cria uma coluna do tipo combobox--- Dim comboBoxCol As New DataGridViewComboBoxColumn 
 '---define o cabecalho (header) --- comboBoxCol.HeaderText = "Disciplinas" 
 '---inclui itens no controle--- comboBoxCol.Items.Add("Matemática") comboBoxCol.Items.Add("Português") comboBoxCol.Items.Add("História") 
 '---Inclui a coluna combobox ao DataGridView--- DataGridView1.Columns.Add(comboBoxCol) 
     | 
Se você deseja permitir que os usuários possam incluir novos valores no controle ComboBox. Neste caso você terá que fazer o seguinte :
1-) Usar o evento EditingControlShowing que ocorre quando o usuário vai tentar editar dados no controle Combobox:
| PrivateSub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms. DataGridViewEditingControlShowingEventArgs) _ Handles DataGridView1.EditingControlShowing Dim comboBoxColumn As DataGridViewComboBoxColumn = DataGridView1.Columns(2) 
     If (cb IsNot Nothing) Then cb.DropDownStyle = ComboBoxStyle.DropDown End IfEnd If End Sub | 
Neste código estou verificando se a célula que esta sendo editada é do tipo ComboBox. Neste caso estou definindo o estilo do ComboBox como DropDown de forma que o usuário possa digitar o novo item a ser incluído.
2-) Usar o evento CellValidating do controle DataGridView que ocorre sempre que o usuário termina de digitar e deixa a célula:
| 
    Private Sub DataGridView1_CellValidating(ByVal 
    sender As Object, ByVal e As System.Windows.Forms.  
    DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating 
         Dim 
    comboBoxColumn As DataGridViewComboBoxColumn = DataGridView1.Columns(2) If (e.ColumnIndex = comboBoxColumn.DisplayIndex) Then If (Not comboBoxColumn.Items.Contains(e.FormattedValue)) Then comboBoxColumn.Items.Add(e.FormattedValue) End If End IfEnd Sub | 
Aqui estou verificando e incluindo o novo item na ComboBox. Para que a inclusão seja possível a propriedade DataSource do coluna DataGridViewComboBoxColumn não pode estar definida; assim não podemos vincular o bindingsource e incluir itens na combobox tendo que usar o código que inclui os dados diretamente na combobox.
|  | 
Eu poderia estender este artigo, mas são tantos os recursos do DataGridView a explorar que vamos continuar a falar sobre assunto mais adiante... Aguarde.
Pegue o 
projeto completo aqui:
 datagridviewTotal.zip
  
datagridviewTotal.zip
Até breve...
| Veja os Destaques e novidades do SUPER DVD VB (sempre atualizado) : clique e confira ! Quer migrar para o VB .NET ? Veja mais sistemas completos para a plataforma .NET no Super DVD .NET , confira... Quer aprender C# ?? 
    Chegou o
    
    Super DVD C# com exclusivo material de 
    suporte e vídeo aulas com curso básico sobre C# | 
   Gostou ?   Compartilhe no Facebook
 Compartilhe no Facebook    Compartilhe no Twitter
 Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Super DVD C# - Recursos de aprendizado na linguagem C#
Curso VB .NET Básico - Vídeo Aulas
Curso C# Basico - Vídeo Aulas