VB
.NET - Preenchendo controles de formulários a partir de um banco de dados - I
![]() |
Neste artigo vou mostrar como podemos preencher controles de formulários Windows Forms a partir de um banco de dados usando a linguagem VB .NET. |
Ao desenvolver uma aplicação desktop usando o template Windows Forms que utiliza um banco de dados teremos que exibir os dados em controles de formulários como TextBox, Label, ComboBox, ListBox, DataGridView, ListView, etc.
É uma tarefa simples mas que pode confundir quem esta iniciando o seu aprendizado na plataforma .NET quer seja usando a linguagem VB .NET ou C#.
Este artigo é voltado para os iniciantes e mostra como podemos acessar dados e exibir informações em controles de formulários procurando adotar boas práticas de programação como a separação de responsabilidades. Nele vamos abordar os cenários mais comuns que podem ocorrer no dia a dia de um desenvolvedor VB .NET.
Quando temos que exibir informações em formulários Windows Forms temos que dividir essa tarefa em duas partes :
Na internet existem toneladas de exemplos de aplicações Windows Forms que acessam dados e exibem informações em controles de formulários, e, creio que 90% delas não respeitam a separação das responsabilidades e misturam o código de acesso a dados com a camada de apresentação geralmente incluindo esse código em eventos dos controles de formulário como Click ou Load. Essa técnica é conhecida como One-Click_Button ou OCB.
O
acróstico OCB
quer dizer one-click-button
, e significa aquele programador que põe um botão no formulário e no seu
evento Click (o evento Load também é muito usado nesta técnica) coloca
centenas de linhas de código que procuram fazer praticamente tudo da
funcionalidade implementada no formulário: obter string de conexão, abrir
conexão , acessar o banco de dados , criar objetos de acesso a dados ,
preencher os controles de formulário , e assim por diante... |
Temos assim uma aplicação que funciona mas que fere as boas práticas e que se torna difícil de manter, de reutilizar e de testar.
Para mostrar que podemos começar fazendo o certo desde o princípio, nesta série de artigos eu vou abordar a estratégia de acesso a dados usando ADO .NET e ferramentas ORM como Entity Framework e NHibernate de forma a criar uma camada de acesso a dados separada da camada de apresentação mostrando com isso as vantagens dessa abordagem.
Recursos usados:
Resistindo à tentação de usar os assistentes de acesso a dados
A plataforma .NET facilita muito o acesso e a apresentação de dados em formulários através de assistentes.
Basta criar uma nova fonte de dados e arrastar a tabela da fonte de dados para o formulário que você terá todos os controles gerados e a conexão criada juntamente com os recursos para incluir, alterar, excluir e consultar dados.
Então porque não usar ?
Esse processo facilita a sua vida no momento mas te oferece um projeto que mistura código de acesso a dados com camada de apresentação, não fornece uma validação de dados robusta e não permite a reutilização de código.
Ou seja você não tem controle sobre o processo, por isso utilize este recurso somente pequenos projetos ou protótipos. Se você quer desenvolver aplicações comerciais robustas resista à tentação.
Cenário I - Acessando o MS Access com ADO .NET
Neste cenário vamos acessar um banco de dados Microsoft Access (.mdb) e exibir informações em controles TextBox de uma aplicação Windows Forms usando a tecnologia ADO .NET.
A primeira coisa que devemos fazer é definir qual banco de dados e quais tabelas desejamos acessar. Para este exemplo eu vou acessar o banco de dados Northwind.mdb e a tabela Customers.
Nota: Se você não possui o banco de dados Northwind.mdb, procure no Google por : 'Northwind.mdb download'. (Os scripts para a versão SQL Server pode ser baixada neste link: http://northwinddatabase.codeplex.com/ )
Vamos então definir uma conexão com este banco de dados abrindo o Visual Studio 2013 Express for windows desktop e a seguir abrindo a janela Database Explorer;
Nesta janela clique com o botão direito sobre Data Connections e a seguir em Add Connection;
Em Data Source clique no botão Change e selecione Microsoft Access DataBase File;
A seguir informe a pasta e o nome Northwind.mdb e clique no botão Test Connection para verificar a conexão;
![]() |
Você deverá ver o banco de dados Northwind.mdb na janela DataBase Explorer conforme figura abaixo:
![]() |
Agora temos que definir a string de conexão e para obter a string de conexão basta selecionar o banco de dados Northwind.mdb na janela DataBase Explorer e pressionar F4.
Na janela de propriedades em Connection String você verá a string de conexão conforme a figura abaixo:
![]() |
Precisamos armazenar a string de conexão para podermos usá-la na criação da conexão com o banco de dados.
Você nunca deve armazenar a string de conexão no seu código isso pode te trazer problemas no futuro se a string de conexão for alterada. Um bom lugar para armazená-la é no arquivo App.Config da aplicação. E vamos fazer isso.
Vamos então criar a nossa solução...
Criando o projeto no Visual Studio 2013 Express
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 Cenario1_MSAccess_AdoNet e clique no botão OK;
![]() |
Agora abra o arquivo App.Config que foi criado e defina uma seção <connectionStrings> e nesta seção defina :
1-
O nome da string de conexão em name :
conexaoNorthwind
2- O seu valor em connectionString: "Provider=Microsoft.Jet.OLEDB.4.0;Data
Source=c:\dados\NorthWind.mdb"
3- O nome do provedor que iremos usar. Para acessar o Microsoft Access usamos o
provedor: System.Data.OleDb
Abaixo vemos os valores definidos no arquivo App.Config:
![]() |
Dessa forma começamos bem pois com a string de conexão armazenada no arquivo App.Config fica fácil alterar e localizar a string de conexão.
Finalmente para poder acessar essa string de conexão a partir da sua aplicação você vai ter que usar a classe ConfigurationManager e essa classe esta no namespace System.Configuration.
Precisamos então incluir uma referência a System.Configuration no nosso projeto.
Clique no menu PROJECT e a seguir em Add Reference;
A seguir selecione o item System.Configuration e clique no botão OK;
![]() |
Agora sim temos tudo pronto e ajustado e podemos partir para a nossa próxima tarefa que é criar uma camada de acesso a dados.
Criando a camada de acesso a dados (Data Access Layer - DAL)
O que é uma Camada de Acesso a Dados ?
É uma camada separada da camada da apresentação de dados que tem a função de efetuar a conexão com a fonte de dados e através de comandos SQL (neste nosso caso) obter os dados para apresentação. Esta separação facilita a manutenção e a portabilidade da aplicação.
A camada de apresentação, quando deseja exibir algum dado, chama a camada de acesso aos dados e solicita a informação.
A camada de apresentação não acessa dados nem a camada de dados faz apresentação. Cada uma cumpre o seu papel.
Uma camada de acesso de dados deve fornecer os seguintes recursos:
Para criar uma camada de acesso a dados podemos adotar duas abordagem :
Na primeira abordagem temos a vantagem de poder gerar um DLL e distribuí-la sendo assim mais reutilizável. Vamos usar esta abordagem.
No menu FILE clique em Add -> New Project;
Selecione o template Windows -> Class Library e informe o nome DAL e clique no botão OK;
![]() |
A seguir vamos renomear a classe Class1.vb, que foi criada com o projeto, com o nome AcessoDB.vb.
A seguir vamos definir o código abaixo nesta classe :
imports System.Data
Imports System.Data.OleDb
Imports System.Configuration
Imports DTO
Public Class AcessoDB
Private Shared Function GetDbConnection() As OleDbConnection
Try
Dim conString As String = ConfigurationManager.ConnectionStrings("CadastroPacientesConnectionString").ConnectionString
Dim connection As OleDbConnection = New OleDbConnection(conString)
connection.Open()
Return connection
Catch ex As Exception
Throw ex
End Try
End Function
Private Shared Sub CloseConnection(conn As OleDbConnection)
Try
If conn.State = ConnectionState.Open Then
conn.Close()
End If
Catch ex As Exception
Throw ex
End Try
End Sub
Public Shared Function ExecuteReader(ByVal sql As String) As IDataReader
Dim reader As IDataReader = Nothing
Using connection As OleDbConnection = GetDbConnection()
Try
Using command As New OleDbCommand(Sql, connection)
reader = command.ExecuteReader()
End Using
Catch ex As Exception
Throw
End Try
Return reader
End Using
End Function
Public Function ExecuteNonQuery(ByVal sql As String) As Integer
Dim i As Integer = -1
Using connection As OleDbConnection = GetDbConnection()
Try
Using command As New OleDbCommand(sql, connection)
i = command.ExecuteNonQuery()
End Using
Catch ex As Exception
Throw
End Try
Return i
End Using
End Function
Public Shared Function ExecuteDataSet(ByVal sql As String) As DataSet
Dim ds As DataSet = Nothing
Using connection As OleDbConnection = GetDbConnection()
Try
Using Command As New OleDbCommand(sql, connection)
ds = ExecuteDataSet()
End Using
Catch ex As Exception
Throw
End Try
Return ds
End Using
End Function
Public Shared Function ExecuteDataSet() As DataSet
Dim da As OleDbDataAdapter = Nothing
Dim cmd As IDbCommand = New OleDbCommand()
Dim ds As DataSet = Nothing
Try
da = New OleDbDataAdapter()
da.SelectCommand = CType(cmd, OleDbCommand)
ds = New DataSet()
da.Fill(ds)
Catch ex As Exception
Throw
End Try
Return ds
End Function
Public Overloads Shared Function GetDataTable(ByVal sql As String, ByVal parameterNames() As String, ByVal parameterVals() As String) As DataTable
Using connection As OleDbConnection = GetDbConnection()
Using da As OleDbDataAdapter = New OleDbDataAdapter(sql, connection)
Dim table As New DataTable
FillParameters(da.SelectCommand, parameterNames, parameterVals)
da.Fill(table)
Return table
End Using
End Using
End Function
Public Overloads Shared Function GetDataTable(ByVal sql As String) As DataTable
Using connection As OleDbConnection = GetDbConnection()
Using da As New OleDbDataAdapter(sql, connection)
Dim table As New DataTable
da.Fill(table)
Return table
End Using
End Using
End Function
Public Shared Function SelectScalar(ByVal sql As String, ByVal parameterNames() As String, ByVal parameterVals() As String) As String
Using connection As OleDbConnection = GetDbConnection()
Using command As OleDbCommand = New OleDbCommand(sql, connection)
FillParameters(command, parameterNames, parameterVals)
Return CStr(command.ExecuteScalar)
End Using
End Using
End Function
Public Shared Function SelectScalar(ByVal sql As String) As String
Using connection As OleDbConnection = GetDbConnection()
Using command As New OleDbCommand(sql, connection)
Return CStr(command.ExecuteScalar)
End Using
End Using
End Function
Public Shared Function CRUD(ByVal sql As String, ByVal parameterNames() As String, ByVal parameterVals() As String) As Integer
Try
Using connection As OleDbConnection = GetDbConnection()
Using command As New OleDbCommand(sql, connection)
FillParameters(command, parameterNames, parameterVals)
Return command.ExecuteNonQuery()
End Using
End Using
Catch ex As Exception
Throw ex
End Try
End Function
Private Shared Sub FillParameters(ByVal command As OleDbCommand, ByVal parameterNames As String(), ByVal parameterVals As String())
Try
If parameterNames IsNot Nothing Then
For i = 0 To parameterNames.Length - 1
command.Parameters.AddWithValue(parameterNames(i), parameterVals(i))
Next
End If
Catch ex As Exception
Throw ex
End Try
End Sub
End Class
|
A classe AcessoDB possui diversos métodos estáticos declarados com o modificado Shared. Dessa forma não precisaremos criar uma instância da classe para acessar os métodos.
A seguir temos os métodos da classe AcessoDB :
É uma classe básica que contém os métodos para realizar as principais tarefas de acesso e manipulação de dados.
A criação da camada de acesso a dados nos leva a pensar em separação de responsabilidades, e, assim a camada de apresentação não deverá conter nada relacionado com o acesso a dados e isso inclui : objetos ADO .NET de acesso a dados, comandos SQL e stored procedures.
Então note que os métodos ExecuteReader(), ExecuteNonQuery(), ExecuteDataSet(), GetDataTable() e SelectScalar() devem receber como parâmetro um comando SQL e para não ter que declarar comandos SQL na camada de apresentação temos que criar outra camada chamada Camada de Negócio ou Businnes Logic Layer - BLL onde iremos realizar as validações referente ao nosso domínio.
Definindo a camada de negócios - BLL
É na camada de negócios que se localizam as regras do negócio e da validação dessas regras. (Existem validações feitas na camada de apresentação mas refere-se a validações de dados entrados pelo usuário apenas).
Então, com uma camada de negócios (BLL) podemos efetuar efetuar uma validação de regra de negócio e em seguida passar os objetos para a camada de apresentação.
No menu FILE clique em Add -> New Project;
Selecione o template Windows -> Class Library e informe o nome BLL e clique no botão OK;
![]() |
A seguir vamos renomear a classe Class1.vb, que foi criada com o projeto, com o nome CustomerBLL.vb pois vamos acessar a tabela Customers.
Além disso vamos criar uma classe chamada Customer nesta camada que irá representar o nosso domínio. A classe Customer deverá possuir apenas as propriedades com os mesmos nomes definidos nos campos da tabela Customers
Clique no menu PROJECT e a seguir em Add Class e informe o nome Customer. A seguir defina o seguinte código nesta classe:
![]() |
Observe que a classe Customers possui propriedades com o mesmo nome dos campos da tabela Customers.
Na nossa aplicação iremos obter as informações do cliente pelo seu código exibindo-as em um formulário nos demais controles TextBox.
O usuário informa o código do cliente e clica no botão procurar que acessa o banco de dados e procurar pelo código do cliente na tabela Customers. Se encontrar as informações serão exibidas nos demais controles:
![]() |
Temos que ter isso em mente para definir o código da classe CustomerBLL. Assim teremos que ter um método que retorne um objeto do tipo Customer que foi definido na classe Customer.
Mas antes de definir o código da camada de negócios BLL observe que agora a nossa aplicação possui 3 camadas assim representadas:
Cada camada é um projeto diferente e o fluxo da informação deve ser feita na seguinte ordem:
![]() |
A camada de apresentação solicita uma informação à camada de negócio que por sua vez a solicita à camada de acesso aos dados que acessa os dados e retorna o resultado para camada de negócio que retorna para a camada de apresentação.
A camada de apresentação não acessa diretamente a camada de acesso aos dados.
Então para que as camadas possam enxergar umas às outras temos que incluir referências nos projetos conforme mostrado a seguir:
1- Clique com o botão direito do mouse sobre o projeto Cenario1_AcessoAdoNet e a seguir em Add -> Reference;
![]() |
2- Agora clique com o botão direito do mouse sobre o projeto BLL e a seguir em Add -> Reference;
![]() |
Agora sim podemos definir os métodos na camada de negócios pois ela já esta acessando as classes da camada de acesso a dados.
Digite o código abaixo na classe CustomerBLL:
Imports DAL
Public Class CustomerBLL
Public Function GetCustomerId(id As String) As Customer
Try
Dim sql As String = "SELECT CustomerID, CompanyName, ContactName, ContactTitle, Region, PostalCode, Country, Phone, Fax FROM Customers WHERE CustomerID = '" & id & "'"
Dim tabela As New DataTable
tabela = AcessoDB.GetDataTable(sql)
Return GetCustomer(tabela)
Catch ex As Exception
Throw ex
End Try
End Function
Public Function GetCustomer(ByVal tabela As DataTable) As Customer Try Dim _customer As New Customer If tabela.Rows.Count > 0 Then _customer.CustomerID = tabela.Rows(0).Item(0) _customer.CompanyName = tabela.Rows(0).Item(1) _customer.ContactName = tabela.Rows(0).Item(2) _customer.ContactTitle = tabela.Rows(0).Item(3) _customer.Address = tabela.Rows(0).Item(4) _customer.City = tabela.Rows(0).Item(5) _customer.Region = IIf(IsDBNull(tabela.Rows(0).Item(6)), "Não Informado", tabela.Rows(0).Item(6)) _customer.PostalCode = tabela.Rows(0).Item(7) _customer.Country = tabela.Rows(0).Item(8) _customer.Phone = tabela.Rows(0).Item(9) _customer.Fax = IIf(IsDBNull(tabela.Rows(0).Item(10)), "Não Informado", tabela.Rows(0).Item(10)) Return _customer Else _customer = Nothing Return _customer End If Catch ex As Exception Throw ex End Try End Function End Class |
Observe que declaramos uma referência ao projeto DAL : Imports DAL
Nesta classe temos dois métodos:
Retorna um objeto do tipo Customer com base no código do cliente. Este método faz uma consulta SQL usando a cláusula Where e procura pelo cliente com o código informado usando o método GetDataTable() da camada DAL.
A seguir este método chama o método GetCustomer() passando o DataTable retornado.
Este método recebe um datatable como parâmetro e retorna um objeto Customer obtido a partir da classe Customer.
Por enquanto é tudo o que precisamos. Vamos agora usar esses métodos na camada da apresentação.
Definindo a camada de apresentação
No formulário form1.vb vamos incluir os seguintes controles a partir da ToolBox:
Disponha os controles conforme o leiaute da figura abaixo:
![]() |
Ao iniciar o projeto o formulário será apresentado e devemos incluir o código do cliente na caixa de texto Código e clicar no botão de comando btnLocalizar. Neste momento vamos chamar o método GetCustomerId() da camada BLL que deverá procurar pelo cliente na camada DAL e retornar os resultados preenchendo os controles do formulário.
Neste momento você deve estar pensando : "Tivemos todo esse trabalho para fazer somente isso ????"
Para fazer uma casa bem construída temos que primeiro fazer um alicerce sólido e foi isso que fizemos : criamos os fundamentos do nosso projeto de forma sólida e a partir de agora podemos desfrutar disso.
Veja como deve ficar o código do formulário associado ao evento Click do botão de comando btnLocalizar :
Imports BLL
Private Sub btnLocalizar_Click(sender As Object, e As EventArgs) Handles btnLocalizar.Click
Try
If String.IsNullOrEmpty(txtCodigo.Text) Then
MessageBox.Show("Informe o código do cliente.", "Codigo", MessageBoxButtons.OK, MessageBoxIcon.Information)
txtCodigo.Focus()
Return
Else
Dim clientebll As New CustomerBLL
Dim cliente As New Customer
cliente = clientebll.GetCustomerId(txtCodigo.Text)
If Not IsNothing(cliente.CustomerID) Then
txtNomeEmpresa.Text = cliente.CompanyName
txtNomeContato.Text = cliente.ContactName
txtTitulo.Text = cliente.ContactTitle
txtEndereco.Text = cliente.Address
txtCidade.Text = cliente.City
txtRegiao.Text = cliente.Region
txtCodigoPostal.Text = cliente.PostalCode
txtPais.Text = cliente.Country
txtTelefone.Text = cliente.Phone
txtFax.Text = cliente.Fax
Else
MessageBox.Show("Cliente não localizado", "Não localizado", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
End If
Catch ex As Exception
MessageBox.Show("Erro ao acessar o cliente", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
|
Executando o projeto e informando um código de cliente podemos ter as situações mostradas a seguir:
a-) O código é
localizado e dos dados do cliente são exibidos nos demais controles de
formulário;
b-) O cliente não é localizado na base de dados;
![]() |
![]() |
Neste primeiro cenário tivemos todo o trabalho para criar os fundamentos da aplicação. Criamos as camadas, definimos os métodos e as referências e agora podemos usar a estrutura criada para realizar as demais tarefas.
Aguarde a continuação do artigo onde irei mostrar como retornar uma lista de clientes e preencher controles de lista.
Pegue o projeto
completo aqui:
Cenario1_AccessAdoNet.zip
Veja
também a vídeo aula relacionada em :
VB .NET - Preenchendo um Combobox e um
ListBox com dados relacionados
João 6:35 Declarou-lhes Jesus. Eu sou o pão da vida; aquele que vem a mim, de modo algum terá fome, e quem crê em mim jamais terá sede.
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 ?
|
Gostou ?
Compartilhe no Facebook
Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#