VB .NET -  DataGridView e DataSet - dicas


Eu creio que você já deve saber o que é um DataSet, mas se anda meio esquecido, vou repetir a definição básica sobre o dataset. Vamos lá...

O objeto DataSet representa uma cópia do banco de dados em memória.

 

Se você já se aventurou a criar algum programa para banco de dados usando o Visual Basic já ouviu pelo menos falar no objeto Recordset . Afinal era ele que permitia o acesso , exibição e a manipulação dos dados.(O objeto DataSet veio para substituir com vantagens o objeto recordset e guarda poucas similaridades com o objeto recordset. )

A classe DataSet contém toda a funcionalidade para gerenciar dados armazenados na memória através de um chache de dados desconectado . Abaixo temos sua estrutura:

Podemos ver que o DataSet contém , tabelas , relacionamentos entre tabelas e cada tabela contém um conjunto de linhas e colunas.  Perceba que o DataSet esta relacionado com Tabelas ( Tables ) e Relacionamentos ( Relations ) e que as tabelas contidas no DataSet pertence a classe DataTable.

Os dados internos contidos em um DataSet são mantidos no formato XML e a estrutura do DataSet é definida pelo XSD (XML Schema Definition Language) , ou seja , XML e DataSet estão intimamente ligados.

A principal característica do DataSet é totalmente desconectado , você pode usar um DataSet para armazenar dados de um banco de dados e pode também mover os dados de um DataSet para um banco de dados , mas o próprio DataSet não faz conexão alguma com o banco de dados , ele nem mesmo tem um objeto para realizar tal conexão .

 

A ligação entre o banco de dados e DataSet é feita pelo objeto DataAdapter (Adaptador de dados). Abaixo uma ilustração que procura mostrar a interação entre os objetos ADO.NET e o modelo desconectado com o DataSet.

Com essa introdução espero sua memória tenha sido refrescada, e, neste artigo eu vou mostrar como criar um DataSet manualmente vinculando-o a um DataGridView onde iremos realizar algumas operações básicas.

Nota: Eu vou criar um DataSet não Tipado. Um dataset tipado possui toda a estrutura das tabelas, e permite o acesso às colunas do banco de dados como se fossem propriedades do dataset.

Abra o seu Visual Basic 2008 Express Edition e crie uma nova solução chamada dgvBasico;

Agora a partir da ToolBox , na guia Data , selecione e arraste o componente DataSet no formulário , form1.vb ,criado na solução;

Surgirá a janela Add DataSet, marque a opção Untyped dataset (dataset não tipado) e clique no botão OK;

Você verá na base do formulário o objeto DataSet; Selecione-o e na janela de propriedades altere o seu nome para dsMacoratti; (ou algo mais sugestivo);

Pronto já temos o nosso dataset não tipado , pois ele não tem nenhuma informação sobre as estruturas que irá conter;

Vamos agora criar uma tabela , para isso selecione a propriedade Tables e clique no botão ao lado;

A janela Tables Collection Editor irá surgir; informe o nome da tabela em TableName(eu dei o nome Macoratti);

Agora temos que criar as colunas da tabela; Na propriedade Columns clique no botão a direita e na janela Columns Collection Editor crie 3 colunas : Codigo, Nome e Nota, conforme a figura abaixo , tomando o cuidado de definir o tipo de dados;

Após encerrar esta etapa teremos o dataset dsMacoratti e a tabela Macoratti contendo os campos codigo, nome e nota;

Inclua então a partir da  ToolBox um controle DataGridView no formulário com o nome gdvAlunos e defina as seguintes propriedades :

O Controle DataGridView suporta o modelo padrão de vinculação dos formulários Windows, e, desta forma pode ser vinculado a uma variedade de fonte de dados. Em muitas circunstâncias você efetuará a vinculação a um componente BindingSource que irá gerenciar os detalhes da interação com a fonte de dados.

O componente BindingSource pode representar qualquer fonte de dados em um formulário Windows e dá a você uma grande flexibilidade quando da seleção ou modificação da localização dos seus dados.

Podemos fazer a vinculação do BindingSource qualquer um dos seguintes objetos/Interfaces:

 

Object

-   System.Type

-   IEnumerable

-   ICollection

-   IList

-   IListSource

-   IBindingList

-   IBindingListView

Resumindo, o componente BindingSource possui duas funções básicas:

  1. Simplificar a vinculação de controles em um formulário a fonte de dados, fornecendo diversos recursos para realizar as operações com dados. Isto é possível pela vinculação do componente a sua fonte de dados e então vincular os controles do formulário ao componente BindingSource. Todas as interações com os dados tais como : navegação, filtragem, atualização, ordenação são feitas pela chamada ao componente BindingSource.
  2. Poder atuar como uma fonte de dados fortemente tipada. O tipo da fonte de dados relacionada é definida através de um dos seguintes mecanismos:
  • Usar o método Add para incluir um item ao componente BindingSource
  • Definir a propriedade DataSource para uma lista , um objeto ou tipo.

A seguir na propriedade Columns do Grid clique para editar as colunas e você verá as colunas definidas na tabela;

Definimos a coluna Codigo como chave primária, com isso não vamos permitir a inclusão de dois códigos iguais;

 Note que pela figura abaixo poderíamos também ter definido a coluna Codigo como AutoIncrement;

Agora vamos incluir no formulário os seguintes controles:

Nosso objetivo é incluir dados no DataGridView a partir do formulário. Então vamos incluir o código abaixo no evento Click do botão de comando Incluir no Grid;

Private Sub btnIncluir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnIncluir.Click
        ' Validação
        If txtCodigo.Text.Length = 0 Then
            MessageBox.Show("Informe o código de identificação", _
                "Codigo", MessageBoxButtons.OK, _
                MessageBoxIcon.Exclamation)
            txtCodigo.Focus()
            Exit Sub
        End If
        If txtNome.Text.Length = 0 Then
            MessageBox.Show("Informe o nome", _
                "Nome", MessageBoxButtons.OK, _
                MessageBoxIcon.Exclamation)
            txtNome.Focus()
            Exit Sub
        End If
        If txtNota.Text.Length = 0 Then
            MessageBox.Show("Informe a nota do aluno", _
                "Nota", MessageBoxButtons.OK, _
                MessageBoxIcon.Exclamation)
            txtNome.Focus()
            Exit Sub
        End If
        '//
        'Obtem um novo registro do formato correto para a tabela
        Dim nova_linha As DataRow = dsMacoratti.Tables(0).NewRow()
        ' Preenche os valores do registro
        nova_linha.ItemArray = New Object() {txtCodigo.Text, txtNome.Text, txtNota.Text}
        ' inclui o registro na tabela
        Try
            dsMacoratti.Tables(0).Rows.Add(nova_linha)
        Catch ex As Exception
            MsgBox(" erro: " & ex.Message)
        End Try
        'limpa os TextBox
        txtCodigo.Clear()
        txtNome.Clear()
        txtNota.Clear()
        'poe o foco no txtCodigo
        txtCodigo.Focus()
        mudaCorCelula()
    End Sub

Com este código incluímos os valores digitados no DataGridView;

Agora vamos um pouco além implementando alguns recursos interessantes no DataGridView:

1- Destacando o cabeçalho de uma coluna com uma cor diferente;

Para isso vamos usar o evento Load do formulário e definir um estilo para a célula do DataGridView de cor amarela;

Private Sub frmGDV_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim estilo_cabecalho As New DataGridViewCellStyle
        'define a cor do cabeçalho e aplica
        estilo_cabecalho.BackColor = Color.Yellow
        gdvAlunos.Columns(2).HeaderCell.Style = estilo_cabecalho
        ' desabilita o estilo visual do cabecalho
        gdvAlunos.EnableHeadersVisualStyles = False
End Sub

O efeito pode ser visto na figura abaixo ao executar o projeto:

2- Colorindo uma célula com base em um critério

Vamos criar uma rotina chamada mudaCorCelula() para alterar a cor da célula Nota quando a nota for menor que 6. (A rotina já esta sendo chamada após a inclusão de valores no Grid;)

 Private Sub mudaCorCelula()
        ' colore as notas abaixo de 6 de cor vermelha fundo branco
        Dim estilo_nota As New DataGridViewCellStyle()
        estilo_nota.BackColor = Color.Red
        estilo_nota.ForeColor = Color.White
        'percorre as linhas da tabela e verifica se o criterio foi atendido
        'alterando definindo o estilo do item no grid
        For r As Integer = 0 To dsMacoratti.Tables(0).Rows.Count - 1
            If dsMacoratti.Tables(0).Rows(r).Item("Nota") < 6 Then
                gdvAlunos.Item(2, r).Style = estilo_nota
            End If
        Next r
    End Sub

 

Executando o projeto e incluindo alguns dados iremos obter:

3- Totalizando os valores de uma determinada coluna

Vamos calcular o total da coluna Nota e exibir o valor em controle label chamado lblTotal colocado bem abaixo desta coluna no formulário.

Para fazer isso usamos o método Compute do objeto DataTable, para somar as notas. Este método calcula o valor de uma expressão na linha atual permitindo usar um filtro;

Sintaxe:

Public Function Compute (expression As String,  filter As String ) As Object

Nota: A expressão requer uma função agregada. Ex:  Count(Quantidade) 

Para o nosso caso podemos usar o seguinte código:

Private Sub btnCalcular_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalcular.Click
        gdvAlunos.DataSource = dsMacoratti
        Dim sumTotal As String = dsMacoratti.Tables(0).Compute("SUM(nota)", String.Empty).ToString
        lblTotal.Text = "TOTAL :" & sumTotal

End Sub

Executando o projeto , após incluir alguns valores e clicar no botão: Calcular total iremos obter:

Para calcular o total para Codigo maior que o valor 1 fazemos assim:

Dim somaTotal As String = dsMacoratti.Tables(0).Compute("SUM(nota)", "Codigo > 1").ToString

Nota: podemos usar também o formato: dsMacoratti.Tables(0).Compute("Sum(Nota)", "Nome like 'Jos'").ToString

Para finalizar ire mostrar algumas das validações que usei neste exemplo para torná-lo mais robusto:

4 - Permitir somente valores numéricos

Usamos o evento KeyPress do controle TextBox e incluímos o seguinte código para permitir somente valores numéricos e o backspace;

 

Private Sub txtNota_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtNota.KeyPress

    'so numeros e backspace

      If Char.IsLetter(e.KeyChar) Then

         e.Handled = True

       End If

End Sub

 

5 - Permitir somente valores alfanuméricos

Usamos o evento KeyPress do controle TextBox e incluímos o seguinte código para permitir somente valores alfanuméricos;

Private Sub txtNome_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtNome.KeyPress

   'so letras e backspace

     If Char.IsNumber(e.KeyChar) Then

        e.Handled = True

      End If

End Sub

Obs: Se você definir a propriedade CharacterCasing do TextBox como igual a Upper todas as letras digitadas sairão em caixa alta;

Com isso espero que as dicas e os conceitos aqui expostos te ajudem em sua empreitada de programador.

Pegue o projeto completo aqui: dgvBasico.zip

Até mais ver...

referências:


José Carlos Macoratti