VB .NET - Exibindo mestre detalhes em controles Windows Forms


Neste artigo eu vou mostrar como podemos exibir detalhes de informações relacionados em controles de formulários em uma aplicação Windows Forms.

O cenário é o seguinte...

Tomando como base o sistema para Geração e controle de parcelamentos  feito na linguagem VB .NET e disponível no Super DVD .NET e no Super CD .NET. , se analisarmos o comportamento do formulário principal teremos:

Formulário principal da aplicação

No formulário principal temos uma visão geral da aplicação onde podemos destacar os seguintes recursos:

1- Exibição da relação dos clientes Cadastrados;
2- Exibição dos detalhes do cliente selecionado;
3- Exibição da informação sobre as parcelas do cliente selecionado;
4- Detalhes dos valores totais, juros e desconto aplicados bem como a opção para visualizar somente as parcelas pagas;
5- O menu da aplicação exibindo as opções para cadastrar : clientes , parcelas, pagamentos , usuários e emitir relatórios;

Pois bem, percebemos que ao selecionar um cliente no controle ListBox os detalhes das informações relacionadas como dados do cliente e dados de suas parcelas são exibidos nos controles de formulário em caixas de texto e no controle DataGridView.

Como podemos implementar este comportamento ?

A primeira coisa que devemos ter para facilitar a implementação é que as tabelas que representam as informações devem estar normalizadas e possuírem um relacionamento entre si.

No caso do sistema para geração de parcelas temos a tabela Clientes que possui as informações dos clientes e a tabela Parcelas com informações sobre os parcelamentos de cada cliente, sendo que essas duas tabelas estão relacionadas entre si pelo campo código do cliente (id e clienteid) conforme mostra a figura abaixo:

Com base nesta informações podemos implementar o comportamento desejado no formulário do projeto Windows Forms:

Primeiro vamos definir uma classe chamada Acesso.vb que deverá conter o método GetConnection() para retornar uma conexão com o banco de dados:

Public Function GetConnection() As OleDbConnection

'Obtem a string de conexão

 

Dim caminhoBD As String = Application.StartupPath

 

If caminhoBD.IndexOf("\bin\Debug") Then

     caminhoBD = caminhoBD.Replace("\bin\Debug", "")

ElseIf caminhoBD.IndexOf("\bin\Release") Then

     caminhoBD = caminhoBD.Replace("\bin\Release", "")

End If

 

caminhoBD = caminhoBD & "\Dados\Parcelas.mdb"
 

Dim strConexao As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & caminhoBD & ";Mode=ReadWrite;Persist Security Info=False"

'Retorna uma conexão.

Return New OleDbConnection(strConexao)

 

End Function

Neste código eu estou usando o banco de dados Parcelas.mdb que esta na pasta \Dados\ no projeto.

Obs: Você pode implementar este método de diversas formas: obtendo a string de conexão do arquivo App.Config, definindo a string no próprio código, etc..

A seguir no formulário que contém os controles ListBox , as caixas de texto e o DataGridView defina no evento Load a carga dos dados no controle ListBox:

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

    preencheListBox()

End Sub

A rotina preencheListBox é dada a seguir:

Private Sub preencheListBox()
 

Using con As OleDbConnection = GetConnection()

   Try

       con.Open()

       Dim sql As String = ("Select id, nome from clientes")

       Dim cmd As OleDbCommand = New OleDbCommand(sql, con)

       Dim da As OleDbDataAdapter = New OleDbDataAdapter(cmd)

       Dim dt As DataTable = New DataTable

       da.Fill(dt)

       lstbClientes.DisplayMember = "Nome"

       lstbClientes.ValueMember = "id"

       lstbClientes.DataSource = dt

Catch ex As Exception

    Throw ex

Finally

     con.Close()

End Try

End Using

End Sub

No evento SelectedIndexChanged do controle ListBox incluímos o código que irá obter o código do cliente e o seu nome e chamar as rotinas exibeDadosCliente() passando o nome do cliente e a rotina exibeParcelasCliente() que exibe as parcelas do cliente passando o código do cliente:

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstbClientes.SelectedIndexChanged
 

    chkParcelasPagas.Checked = False

   ' obtem o nome selecionado no listbox

    cliente = lstbClientes.Text

    codigo = lstbClientes.SelectedValue


    ' exibe os dados do cliente e as informações sobre suas parcelas

    exibeDadosCliente(cliente)

    exibeParcelasCliente(codigo)
 

End Sub

 

A rotina exibeDadosCliente() recebe como parâmetro o nome do cliente(nome) e executa uma consulta SQL filtrando por nome , obtendo um DataReader e preenchendo as caixas de texto:

Private Sub exibeDadosCliente(ByVal nome As String)
 

   Dim dr As OleDbDataReader = Nothing

   ' abre a conexao

   Using con As OleDbConnection = GetConnection()

   con.Open()

   ' cria um command para esta conexao

   Dim cmd As New OleDb.OleDbCommand("SELECT * FROM Clientes WHERE Nome=?", con)

   ' Cria uma consulta paremetrizada

   cmd.Parameters.Add(New OleDb.OleDbParameter("Nome", nome))

   Try

     'executa a consulta.

     dr = cmd.ExecuteReader(CommandBehavior.SingleRow)

     'exibe o resultado nas caixas de texto

     If dr.HasRows Then dr.Read()
       txtCodigo.Text = dr.Item(
"id")

       txtDocumento.Text = dr.Item("documento")

       txtNome.Text = dr.Item("Nome").ToString

       txtEndereco.Text = dr.Item("Endereco").ToString

       txtCidade.Text = dr.Item("Cidade").ToString

       txtUF.Text = dr.Item("uf").ToString

       txtCep.Text = dr.Item("Cep").ToString

       txtEmail.Text = dr.Item("email")

       txtTelefone.Text = dr.Item("telefone")

     Else

       'limpa as caixas de texto

        For Each ctl As Control In Me.Controls

           If TypeOf ctl Is TextBox Then ctl.Text = ""

        Next ctl

     End If

Catch ex As Exception

    Throw ex

Finally

   dr.Close()

   'fecha a conexao

   con.Close()

End Try

End Using

End Sub

 

A rotina exibeParcelasCLiente() recebe como parâmetro o código do cliente(cod) e executa uma instrução SQL e obtém um DataTable contendo as parcelas relacionadas ao cliente exibindo-as no controle DataGridView:

Private Sub exibeParcelasCliente(ByVal cod As Integer )
 

Using con As OleDbConnection = GetConnection()

    Try

    con.Open()

    Dim sql As String

    sql = "SELECT parcelaid,clienteid,valorParcela,numeroParcela,vencimentoParcela,pagamentoParcela,desconto,juros,observacao FROM Parcelas              WHERE clienteid=?"
 

    ' cria um command para esta conexao

   Dim cmd As New OleDb.OleDbCommand(sql, con)


    ' Cria uma consulta paremetrizada

    cmd.Parameters.Add(New OleDb.OleDbParameter("Codigo", cod))


    Dim
da As OleDbDataAdapter = New OleDbDataAdapter(cmd)

    Dim dt As DataTable = New DataTable


    da.Fill(dt)

    gdvParcelas.DataSource = dt
    'formata o DataGridView

    formataGridView()

Catch ex As Exception

    Throw ex

Finally

    con.Close()

End Try

End Using

End Sub

 

O código é muito simples e procura mostrar como implementar este comportamento; assim quando um cliente for selecionado no ListBox os dados serão atualizados nos demais controles de formulário.

Simples, simples assim...

Eu sei é apenas VB .NET, mas eu gosto...

Referências:

José Carlos Macoratti