Clique aqui para ler este artigo em pdf imagem_pdf.jpg

msdn02_capa.jpg

Clique aqui para ler todos os artigos desta edição

 

Treinamento em ASP.NET (Parte II)

por Renato Haddad

 

Vamos à segunda parte do treinamento em ASP.NET, na qual você aprenderá a manipular alguns dos controles utilizados com mais freqüência durante o acesso a banco de dados. Atualmente é normal que os dados fiquem armazenados em alguma fonte de dados, seja um banco de dados no SQL Server, Oracle, MS-Access, DB2 ou então, em arquivos XML e textos. No .NET, isso é completamente transparente, ou seja, não importa onde estejam os dados.

 

Na parte I, você aprendeu a criar uma solução. Então, abra a solução MSDNMag (criada na parte I) e adicione um novo formulário, (Add / Add Web Form) denominado BancoDados.aspx. Selecione o menu View / Toolbox ou pressione Ctrl + Alt + X para exibir a Toolbox. Monte um formulário semelhante ao da Figura 1, contendo os seguintes itens: uma tabela para alinhamento dos dados, um DropDownList, um RadioButtonList, três Buttons, um Label, um CheckBoxList e um DataGrid. Para inserir todos esses controles, clique neles e arraste-os no documento. Para digitar qualquer texto no documento, clique na devida posição do formulário e digite os respectivos textos: Bando de Dados – ASP.NET”, “Categorias”, “Colunas:” e “Direção:”. Para formatar um texto, basta seleciona-lo e então aplicar as formatações existentes na barra de ferramentas.

Dica: Sempre que você quiser mudar de linha pressione ENTER ou SHIFT + ENTER. Existe uma diferença sutil no espaçamento, onde ENTER provoca um novo parágrafo e SHIFT + ENTER provoca uma quebra de linha. Não esqueça que para digitar no corpo do documento é necessário que a propriedade pageLayout de sua página esteja definida como FlowLayout.

 

image002.gif
Figura 1 –
Design da página

 

Exiba a janela de propriedades (F4) e configure as propriedades dos controles de acordo com a Tabela 1: note que o AutoPostBack do dropColunas e do rdDirecao devem estar definidos como True, ou a página não será enviada ao servidor para o processamento. Essa propriedade provoca um Post na página, ou seja, ela submete a solicitação ao servidor.

 

DropDownList (ID)

DropColunas

AutoPostBack

True

Items (Collection)

Crie uma lista de 1 a 5, tanto para Text como para Value

RadioButtonList (ID)

rdDirecao

AutoPostBack

True

Items (Collection)

Crie a seguinte lista: Horizontal e Vertical, tanto para Text como para Value

CheckedBoxList (ID)

CkCategorias

Button1 (ID)

BtnLimpa

Text

Limpa Todas

Button2 (ID)

BtnSeleciona

Text

Seleciona Todas

Button3 (ID)

btnPesquisar

Text

Pesquisa os produtos das categorias selecionadas

Label1 (ID)

lblProdutos

Text

Branco

DataGrid1 (ID)

gridProdutos

Visible

False

Tabela 1 – Propriedades dos controles

 

Com relação ao DataGrid, você pode formatá-lo de acordo com as opções de formato pré-definidas. Para isso, pressione o botão direito sobre o controle e selecione AutoFormat. Escolha um formato de acordo com a sua necessidade e observe que as propriedades do estilo serão configuradas automaticamente.

O banco de dados usado como exemplo é o Northwind, que está instalado no SQL Server. O funcionamento se dará da seguinte forma: na primeira vez que a página for carregada, o controle ckCategorias será preenchido com todas as categorias existentes na tabela Categories do banco de dados. Com isso, o internauta poderá selecionar qualquer categoria existente neste controle. Quando você pressionar o botão btnPesquisar, serão exibidos no gridProdutos todos os produtos referentes às categorias selecionadas. Os demais controles existem para que possamos explorar a parte de design interativo com os internautas, ou seja, você pode criar uma página para que o internauta a configure de acordo com as opções selecionadas. Esse processo é possível porque os controles permitem atribuir propriedades em tempo de execução, dispensando completamente a edição manual do design. Esse é um dos pontos fortes do ASP.NET.

Agora que você já conhece o design da página e como deverá funcionar, o próximo passo será digitar os códigos. Para isso, pressione F7 ou View / Code. Como vamos acessar um banco de dados SQL Server, digite na primeira linha a referência da classe do SQL Server. A classe SqlClient foi criada especialmente para o SQL Server versão 7.0 ou superior. Nos outros bancos de dados, você pode usar o OleDb.

 

Imports System.Data.SqlClient

 

Como iremos abrir o banco de dados em dois lugares, para facilitar a declaração da conexão, declare a variável conexão antes do evento Page_Load. Essa variável é do tipo String e contém o nome do banco de dados (Database), o nome do servidor (Server) e o usuário (User ID) de acordo com suas especificações da instalação do SQL Server na sua máquina. Caso necessite, declare a Password e os demais parâmetros da conexão. É importante ressaltar que todos os parâmetros declarados na conexão dependem de como você fez a sua instalação do SQL Server, os usuários existentes, as senhas e se tem ou não segurança integrada. Caso você execute a página e ocorra um erro de login ou conexão, verifique estes itens para que o código possa acessar o banco de dados Northwind.

 

Dim conexao As String = "Database=Northwind;Server=NomeServidor;user id=sa"

 

Digite o código no evento Page_Load (Listagem 1) para preencher o controle ckCategorias com todas as categorias existentes no banco de dados. Vale dizer que esse evento será executado todas as vezes que a página for carregada. No entanto, as categorias não mudam, e a pergunta é: por que então carregar todas as vezes que a página for executada? Realmente, não há a menor razão para isso e, desse modo, é possível verificar este fato através do Page.IsPostBack, ou seja, tudo o que estiver dentro deste bloco será executado apenas na primeira vez que a página for carregada. O restante da explicação está em cada uma das linhas da Listagem 1.

 

Listagem 1. Código do evento Page_Load

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

    'Verifica se foi dado algum Post na página

    If Not Page.IsPostBack Then

       'Este código é executado apenas na primeira vez

       'que a página é carregada, depois nunca mais!!!

       'Declara a conexão

       Dim conn As SqlConnection

       'Define a string SQL

       Dim sql As String = "SELECT CategoryID, CategoryName FROM Categories ORDER BY CategoryName"

       'Declara o Adapter e o DataSet

       Dim da As SqlDataAdapter

       Dim ds As DataSet

       'Monta a estrutura de erro

       Try

            'Instancia e abre a conexão usando a variável

            'conexão declarada anteriormente

            conn = New SqlConnection(conexao)

            conn.Open()

            'Instancia o Adapter contendo o SQL e a conexão

            da = New SqlDataAdapter(sql, conn)

            ds = New DataSet

            'Monta uma tabela na memória denominada categorias

            'contida dentro do Dataset ds

            da.Fill(ds, "categorias")

            'Configura as propriedades do checkBoxList

            With ckCategorias

                'Define que campo será exibido

                .DataTextField = "CategoryName"

                'Define que campo será armazenado

                .DataValueField = "CategoryID"

                'Define a origem do controle que é a tabela

                'categorias que está na memória

                .DataSource = ds.Tables("categorias").DefaultView

                'Preenche o controle

                .DataBind()

            End With

            'Caso ocorra ou não um erro, fecha a conexão

        Finally

            conn.Close()

        End Try

    End If

End Sub

 

 

Mas o que é um DataSet (usado no código da listagem 1)? DataSet é uma representação de uma ou mais tabelas na memória (contendo os métodos Select, Insert, Delete e Update) e é possível inclusive estabelecer relacionamentos entre elas. Isso significa dizer que podemos ter um DataSet contendo diversas tabelas.

Pelo fato de essa representação ser feita na memória, tudo é mais rápido. A grande característica do ADO.NET é trabalhar com dados desconectados, ou seja, todas as alterações são feitas na memória até que você as efetive no banco de dados.

 

Voltando ao exemplo: como todas as categorias estão listadas e dispõem de um checkbox para cada categoria, vamos facilitar a vida do internauta. Caso o internauta queira selecionar todas as categorias existentes, para que ele não precise clicar em cada categoria, podemos montar um código que faça isso automaticamente. A mesma idéia serve para desmarcar todas as categorias selecionadas. O código da Listagem 2 deverá ser implementado para os botões btnLimpa e btnSeleciona, portanto, dê um duplo clique em cada botão e digite o código que chama a rotina ChecaCategorias passando como parâmetro o True ou False. Esta rotina irá percorrer todos os checkbox do controle ckCategorias e atribui o True ou False para cada checkbox existente.

 

Listagem 2. Código para desmarcar ou selecionar todas as categorias

Private Sub btnLimpa_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLimpa.Click

    ChecaCategorias(False)

End Sub

 

Private Sub btnSeleciona_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSeleciona.Click

    ChecaCategorias(True)

End Sub

 

Private Sub ChecaCategorias(ByVal checa As Boolean)

    'Declara um objeto do tipo ListItem

    Dim objItem As ListItem

    'Monta um looping para varrer todas as categorias

    For Each objItem In ckCategorias.Items

        'Para cada item atribui o conteúdo da variável

        'checa se pode ser True/False

        objItem.Selected = checa

    Next

    'Oculta os controles

    gridProdutos.Visible = False

    lblProdutos.Visible = False

End Sub

 

Para configurar as propriedades do ckCategorias em tempo de execução, é possível criar duas possibilidades: primeiro, configurar o número de colunas que serão exibidas. Para isso, dê um duplo clique no controle dropColunas e digite o código a seguir, que atribui à propriedade RepeatColumns o número de colunas selecionadas no DropColunas. Só um lembrete para quem já fez isso em ASP, PHP ou qualquer outro Script: veja como é fácil no ASP.NET, é apenas uma linha!

 

Private Sub dropColunas_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles dropColunas.SelectedIndexChanged

    ckCategorias.RepeatColumns = dropColunas.SelectedValue

End Sub

 

A segunda possibilidade é escolher a direção em que os dados serão exibidos: horizontal ou vertical. Para isso, dê um duplo clique no controle rdDirecao e digite o código que verifica qual foi a opção selecionada. Observe que, para isso, basta configurar a propriedade RepeatDirection. Mais um lembrete: será que é tão fácil assim em outras linguagens? Veja o ganho de produtividade.

 

Private Sub rdDirecao_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles rdDirecao.SelectedIndexChanged

    If rdDirecao.SelectedValue = "Horizontal" Then

        ckCategorias.RepeatDirection = RepeatDirection.Horizontal

    Else

        ckCategorias.RepeatDirection = RepeatDirection.Vertical

    End If

End Sub

 

A grande facilidade do ASP.NET é demonstrada aqui. Após selecionar as categorias, você precisa montar o DataGrid com todos os produtos, de acordo com as respectivas categorias selecionadas. A construção desse código é relativamente simples porque basta você aplicar um filtro à cláusula Where do SQL. No entanto, como o Internauta pode selecionar uma ou todas as categorias, o filtro precisará ser montado de forma que o looping percorra todos os itens do ckCategorias e verifique quais estão selecionados. Para cada item selecionado, é concatenada uma variável que contém o respectivo ID da categoria para executar o DataReader com a string SQL.

Quando usar um DataReader? Use o DataReader sempre que precisar ler uma fonte de dados; o DataReader é do tipo Forward Only, ou seja, você não consegue navegar em registros anteriores. Em termos de performance, um DataReader é muito mais rápido que um DataAdapter. A desvantagem é que você não conseguirá aplicar paginação em um DataGrid se este tiver sido preenchido com um DataReader, como é o caso deste exemplo.

Você irá notar que, na concatenação de strings, estou usando a classe System.Text.StringBuilder. Sempre que você precisar concatenar strings, opte pelo StringBuilder. Ele é infinitamente mais rápido que outras formas de concatenação, por exemplo, variável = variável + conteúdo ou variável += conteúdo ou variável = variável & conteúdo.

 

Private Sub btnPesquisar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPesquisar.Click

    'Define a conexão, o Command, o DataReader e a string SQL

    Dim conn As New SqlConnection(conexao)

    Dim cmd As New SqlCommand

    Dim Reader As SqlDataReader

    Dim sql As New System.Text.StringBuilder

    sql.Append("Select ProductName, UnitsInStock, UnitPrice FROM Products ")

    'Como esta condição deverá ser montada em tempo de execução, pois vc

    'não sabe quais itens o internauta irá selecionar, é preciso montar um

    'looping para varrer todos os itens do CheckBoxList e, caso esteja

    'selecionado, capturar o valor e adicioná-lo à string da cláusula Where do SQL

    Dim condicao As New System.Text.StringBuilder

    condicao.Append(" Where CategoryID IN (")

    Dim ItemSelecionado As Boolean = False

    For contador As Integer = 0 To ckCategorias.Items.Count - 1

        'Verifica se o item atual está selecionado

        If ckCategorias.Items(contador).Selected Then

            ItemSelecionado = True

            'Caso esteja, captura o valor e o armazena na variável condicao

            condicao.Append(ckCategorias.Items(contador).Value + ", ")

        End If

    Next

    'Como condicao é uma variável que poderá conter diversos itens, a string

    'SQL requer que todos os itens estejam entre parênteses, portanto,

    'esta linha adiciona o fecha parênteses à condicao

    condicao.Append(")")

    'Verifique que no looping cada item selecionado

    'é inserido na variável condição seguido do

    'respectivo separador de items (vírgula).

    'No entanto, para arrumar a sintaxe do SQL,

 'é preciso substituir ", )" por ")"

'No final, basta concatenar as duas variáveis

    condicao = condicao.Replace(", )", ")")

    sql.Append(condicao)

    'Abre a conexão, monta o Command e executa o DataReader

    conn.Open()

    cmd = New SqlCommand(sql.ToString(), conn)

    If ItemSelecionado Then

        Reader = cmd.ExecuteReader()

        'Exibe o DataGrid de produtos e o Label

        gridProdutos.Visible = True

        lblProdutos.Visible = True

        'Define a origem do DataGrid

        gridProdutos.DataSource = Reader

        'Preenche o DataGrid

        gridProdutos.DataBind()

        'Exibe um texto contendo o número de produtos do DataGrid

        lblProdutos.Text = "Existem " + gridProdutos.Items.Count.ToString() + " produtos."

        'Fecha o DataReader e a conexão

        Reader.Close()

    End If  

    conn.Close()

End Sub

 

Após digitar todo o código, abra o Solution Explorer, clique com o botão direito sobre o BancoDados.aspx e selecione Set As Start Page. Compile e execute no navegador (Ctrl + F5) para ver o resultado. A Figura 2 exibe o DataGrid e todos os 52 produtos das categorias selecionadas.

 

image004.jpg

Figura 2 – Execução da página

 

Conclusões

O ASP.NET nos permite interagir com o internauta de forma simples e objetiva com apenas algumas linhas de programação, personalizando a exibição do conteúdo da página para o internauta. Quanto ao acesso a fontes de dados, use e abuse das classes e controles de que o ASP.NET dispõe; afinal, programar para Web está cada vez mais simples, fácil e produtivo. “No stress, think .NET”.


Referências:

http://www.asp.net

http://www.gotdotnet.com

http://www.codeproject.com

http://www.linhadecodigo.com.br