Utilizarei o Visual Studio 2008 com o SQL
Server 2005 e o banco de dados Northwind, porém os mesmos passos podem
ser seguidos no Visual Studio 2005 com o SQL Server 2000.
Crie um novo projeto Web no Visual Studio, logo em seguida clique com o botão direito sobre a solução e escolha Add / New Item.

Na janela que se abrirá, selecione o Item DataSet e atribua o nome DsTerritorio.

Com o DataSet criado, clique com o botão direito dentro da janela do DataSet, escolha
Add / TableAdapter, abrirá uma janela solicitando qual conexão com o
banco de dados será utilizado para a construção do TableAdapter, crie a
conexão com o SQL Server e salve com o nome NorthwindConn e clique em
Next.


Na próxima janela selecione como o
TableAdapter acessará o banco de dados, as opções possíveis são: SQL
statements, criar nova Stored Procedure ou utilizar uma Stored
Procedure já existente no banco de dados.
Deixe a opção Use SQL statements marcada e clique em Next.

A próxima janela é onde se insere o código
SQL para o retorno dos dados, porém você pode utilizar o Query Builder,
que é a ferramenta visual para construção de instruções SQL, portanto
clique no botão Query Builder.

Após clicar no botão Query Builder,
aparecerão duas janelas, a janela do próprio Query Builder e a janela
de Add Table, a segunda janela já com as tabelas existentes no banco de
dados.
Procure e selecione a tabela Region, em seguida, clique em Add. A tabela Region aparecerá no Query Builder.

Clique em Close, em seguida, selecione as
duas colunas da tabela Region (RegionID e RegionDescription). Agora
clique em Execute Query.

Se o resultado do Execute Query for igual
à figura acima, clique em Ok. A próxima janela solicitará nomes para os
métodos de Fill e Return que por padrão são Fill e GetData
respectivamente.
Para a tabela Region, deixe os nomes
sugeridos e clique em Next. A próxima janela exibirá o sumário da
criação do TableAdapter. Clique em Finish.


Agora já é possível visualizar o TableAdapter dentro do DataSet dsTerritorio.

Ainda dentro do DataSet dsTerritorio, crie
outro TableAdapter. Novamente, clique com o botão direito dentro do
DataSet, escolha Add / TableAdapter, escolha a conexão com a base de
dados, também escolha Use SQL statements.
Na janela do Query Builder, adicione a
tabela Territories, selecione todas as colunas. Na linha RegionID,
insira o parâmetro @RegionID na coluna Filter. O parâmetro será
responsável por aplicar o filtro de qual região o SQL retornará os
territórios.

Na janela de definições dos métodos,
acrescente a expressão ByRegionID, após Fill e GetData. Dessa maneira
apenas pelo nome do método é possível saber que um parâmetro chamado
RegionID é esperado.


Agora que concluiu a criação do DataSet
dsTerritorio, crie o DataSet dsVendedor, e dentro dele crie um
TableAdapter com o SQL abaixo.
SELECT EmployeeTerritories.EmployeeID,<br /> Employees.FirstName + ' ' + Employees.LastName AS FullName,<br /> EmployeeTerritories.TerritoryID<br />FROM Employees INNER JOIN EmployeeTerritories<br /> ON Employees.EmployeeID = EmployeeTerritories.EmployeeID<br />WHERE (EmployeeTerritories.TerritoryID = @TerritoryID)
Acrescente ByTerritoryID na definição dos métodos Fill e GetData.
Após clicar em Finish, o TableAdapter
criado estará com os nomes DataTable1 e DataTable1TableAdapter,
altere-os para Employee e EmployeeTableAdapter.

Crie um novo DataSet chamado dsCliente, e também crie um novo TableAdapter com o código abaixo.
SELECT Customers.CustomerID, Customers.CompanyName, CustomerEmployee.EmployeeID<br />FROM (SELECT CustomerID, EmployeeID<br /> FROM Orders<br /> GROUP BY CustomerID, EmployeeID) AS CustomerEmployee INNER JOIN<br /> Customers ON CustomerEmployee.CustomerID = Customers.CustomerID<br />WHERE (CustomerEmployee.EmployeeID = @EmployeeID)Para os nomes dos métodos Fill e GetDate, não esqueça de adicionar ByEmployeeID em ambos.
Como no TableAdapter de vendedores, os
nomes deste TableAdapter também não estão corretos, altere-os para
Customers e CustomersTableAdapter respectivamente.
Para concluir a construção dos DataSets, crie mais um chamado dsPedido e também crie um novo TableAdapter com o código abaixo.
SELECT OrderID, CustomerIR, EmployeeID, OrderDate, ShippedDate,<br /> ShipName, ShipAddress, ShipCity, Shipcountry<br />FROM Orders<br />WHERE (CustormerID = @CustomerID) AND<br /> (EmployeeID = @EmployeeID)Acrescente ByCustomerIDEmployeeID aos métodos Fill e GetData e clique em Finalizar.
Agora crie o último TableAdapter chamado OrderDetails conforme a figura abaixo.
Após a criação de todos os DataSets (Território, Vendedor, Cliente e Pedido) o projeto deve estar conforme a figura abaixo.

Copie os seguintes arquivos do diretório
de instalação do WebOrb (por padrão em c:\inetpub\wwwroot\weborb30)
para o diretório do projeto .NET.
/weborb.config
/bin/weborb.dll
/WEB-INF
Adicione o código XML abaixo ao web.config do projeto .NET.
<configuration><br /> <system.web><br /> <httpHandlers><br /> <add verb="*" path="weborb.aspx" type="Weborb.ORBHttpHandler"/><br /> <add verb="*" path="codegen.aspx" type= "Weborb.Management.CodeGen.CodegeneratorHttpHandler"/><br /> </httpHandlers><br /> </system.web><br /></configuration>É preciso referenciar o weborb.dll ao
projeto, para isso no Solution Explorer do Visual Studio, clique duas
vezes sobre a opção My Project, em seguida clique em References e
depois em Add / References?
Clique na aba Browse, localize o diretório
Bin do projeto, selecione o arquivo weborb.dll e clique em OK, salve o
projeto e feche a janela My Project.
Clique com o botão direito sobre a solução e escolha Add / New Item, porém escolha Class e dê o nome de csFlex.vb.
Nesta classe serão criados os métodos de
chamada e retorno dos DataSets e TableAdapters criados anteriormente,
através desses métodos é que a comunicação entre o .NET e o Flex
ocorrerá.
Insira o código abaixo ao arquivo csFlex.vb
Imports Weborb.Service<br /> <br />Public Class csFlex<br /> <br /> Public Function getRegion() As DataTable<br /> Return New dsTerritorioTableAdapters.RegionTableAdapter().GetData()<br /> End Function<br /> <br /> Public Function getTerritories(ByVal RegionID As String) As DataTable<br /> Return New dsTerritorioTableAdapters.TerritoriesTableAdapter().GetDataByRegionID(RegionID)<br /> End Function<br /> <br /> Public Function getEmployee(ByVal TerritoryID As String) As DataTable<br /> Return New dsVendedorTableAdapters.EmployeeTableAdapter().GetDataByTerritoryID(TerritoryID<br /> End Function<br /> <br /> Public Function getCustomers(ByVal EmployeeID As String) As DataTable<br /> Return New dsClienteTableAdapters.CustomersTableAdapter().GetDataByEmployeeID(EmployeeID)<br /> End Function<br /> <br /> Public Function getOrders(ByVal CustomerID As String, ByVal EmployeeID As String) As DataTable<br /> Return New dsPedidoTableAdapters.OrdersTableAdapter().GetDataByCustomerIDEmployeeID(CustomerID, EmployeeID)<br /> End Function<br /> <br /> Public Function getOrderDetails(ByVal OrderID As String) As DataTable<br /> Return New dsPedidoTableAdapters.OrderDetailsTableAdapter().GetDataByOrderID(OrderID)<br /> End Function<br /> <br />End ClassSalve e feche o arquivo csFlex, agora
compile o projeto. Caso o Visual Studio sinalize algum erro, volte e
execute os passos novamente.
Antes de criar a interface no Adobe Flex,
crie a aplicação Web no Internet Information Services (IIS) com o nome
do projeto, verifique se ao acessar o endereço através do navegador uma
página em branco é exibida.
Agora já com a aplicação web configurada
no IIS, abra o Adobe Flex Builder 3, adicione um novo projeto (File /
New / Flex Project).
Agora defina o nome do Projeto, se a opção
Use default location estiver marcada, desmarque-a e localize o endereço
do projeto .NET e dentro da pasta do projeto crie uma nova pasta
chamada FlexSrc. O Project location do Flex deve ficar como a figura
abaixo. A opção de Application type deixe marcado Web Application, e em
Server technology selecione ASP.NET. Clique em Next.
Na próxima janela, na opção Server
selecione Use Internet Information Services (IIS), em Web application
root informe o diretório raiz da aplicação web definida no IIS e no
campo Web application URL informe o endereço da aplicação no IIS. Após
clicar no botão Validate Configuration, na parte superior da janela o
Flex Builder deve ser informar: “The web application root and URL are
valid”, caso apareça outra mensagem, os endereços informados não estão
corretos, corrija antes de prosseguir.
Na mesma janela, um pouco abaixo está
definida a pasta bin-debug como local a serem salvos os arquivos Flex
compilados, deixe o nome que o Builder sugeriu e clique Next.
Na última janela de configuração do
projeto Flex, é possível definir qual a pasta onde o Flex Builder
salvará os arquivos fontes, bem como qual o nome do primeiro arquivo do
projeto a ser criado.
Deixe os campos preenchidos como o Builder
sugeriu e clique em Finish. Após alguns segundos o Adobe Flex Builder 3
exibirá o arquivo ArtigoFlex.mxml pronto para o início da construção da
interface da aplicação.
Porém antes começar a codificar é
necessário incluir um argumento de compilação ao projeto, pois sem esse
argumento o Flex não conseguirá acessar os métodos construídos na
classe csFlex. Para incluir o argumento, clique com o botão direito
sobre o nome do projeto no Flex Navigator e em seguida clique em
Properties. Com a janela de propriedades aberta, clique sobre a opção
Flex Compiler, e insira o argumento após o argumento ?locale en_US
-services c:\Inetpub\wwwroot\weborb30\web-inf\flex\services-config.xmlApós inserir o argumento services, clique em OK.
Agora com o projeto corretamente
configurado e pronto para comunicar com o .NET é possível iniciar a
construção da interface, para tanto crie um painel, entre as tags ,
com o título Painel de Vendas, esse painel terá um tamanho ajustável
conforme as dimensões do navegador do cliente, para isso configure as
propriedades left, right, top e bottom, todos com o valor 10.
<mx:Panel layout="absolute" left="10" right="10" top="10" bottom="10" title="Painel de Vendas"><br /></mx:Panel>É possível verificar como o projeto está ficando, bastar clicar no Play.
Dentro do painel, crie um canvas na cor cinza.
<mx:Canvas height="42" left="0" top="0" right="0" backgroundColor="#F3F3F3" borderStyle="none" borderThickness="1" borderColor="#C2BEBE"><br /> <br /></mx:Canvas>Dentro do canvas coloque os labels e
comboboxs que serão utilizados para selecionar região, território,
vendedor e cliente, coloque também dentro do canvas o botão consultar.
<mx:Label y="12" text="Região" horizontalCenter="-348"/><br /><mx:ComboBox y="10" id="cbRegion" labelField="RegionDescription" width="89" horizontalCenter="-274"></mx:ComboBox><br /><mx:Label y="12" text="Território" horizontalCenter="-194"/><br /><mx:ComboBox y="10" id="cbTerritory" labelField="TerritoryDescription" width="89" horizontalCenter="-114"></mx:ComboBox><br /><mx:Label y="12" text="Vendedor" horizontalCenter="-32"/><br /><mx:ComboBox y="10" id="cbEmployee" labelField="FullName" width="89" horizontalCenter="49"></mx:ComboBox><br /><mx:Label y="12" text="Cliente" horizontalCenter="124"/><br /><mx:ComboBox y="10" id="cbCustomer" labelField="CompanyName" width="89" horizontalCenter="198"></mx:ComboBox><br /><mx:Button y="10" label="Consultar" width="119" horizontalCenter="310" id="btConsultar"/>A propriedade horizontalCenter define qual
a distância em pixel que um objeto está do centro da página, valores
negativos representam objetos a esquerda do centro da tela e valores
positivos representam objetos a direita, os valores definidos garantem
que os objetos estarão sempre centralizados.
labelField é a propriedade que define qual
o campo que será exibido como label do combobox. O Adobe Flex trabalha
de maneira diferente do .NET quando o assunto é combobox ou
dropdownlist, pois no .NET é possível definir apenas dois valores ao
dropdownlist, o datatextfield e o datavalueFfeld, já no Adobe Flex só
se define qual será o valor de exibição do combobox, labelField, pois
cada linha de opção do combobox é um objeto com propriedades. Essas
propriedades são as colunas que retornaram do banco de dados, logo você
não tem acesso a somente duas colunas como dropdownlist, você tem
acesso a todas as colunas que retornaram do banco de dados.
A propriedade Y define qual a distância
que o objeto tem do topo do componente ao qual ele está pertencendo,
neste caso, y=”12″ diz ao Flex que o label está a 12 pixel do topo do
canvas.
Após o canvas inclua um datagrid onde serão exibidos os pedidos resultantes da consulta ao banco de dados.
<mx:DataGrid id="dgPedido" right="10" left="10" top="55" bottom="10"><br /><mx:columns><br /> <mx:DataGridColumn headerText="Detalhes" width="85"/><br /> <mx:DataGridColumn headerText="Data Pedido" dataField="OrderDate"/><br /> <mx:DataGridColumn headerText="Data Entrega" dataField="ShippedDate"/><br /> <mx:DataGridColumn headerText="Entregue para" dataField="ShipName"/><br /> <mx:DataGridColumn headerText="Endereço" dataField="ShipAdress"/><br /> <mx:DataGridColumn headerText="Cidade" dataField="ShipCity"/><br /> <mx:DataGridColumn headerText="País" dataField="ShipCountry"/><br /></mx:columns><br /></mx:DataGrid>Para fazer a comunicação entre a interface
Flex e a aplicação server-side .NET utilize o componente RemoteObject
do Adobe Flex 3.
<mx:RemoteObject id="roNet" destination="GenericDestination"<br /> source="ArtigoFlex.csFlex" showBusyCursor="true"<br /> fault="faultHandler(event)" ><br /> <br /> <mx:method name="getRegion" result="gotRegion(event)" /><br /> <mx:method name="getTerritories" result="gotTerritories(event)" /><br /> <mx:method name="getEmployee" result="gotEmployee(event)" /><br /> <mx:method name="getCustomers" result="gotCustomers(event)" /><br /> <mx:method name="getOrders" result="gotOrders(event)" /><br /> <mx:method name="getOrderDetails" result="gotOrderDetails(event)" /><br /> <br /></mx:RemoteObject>A propriedade destination deve sempre ser
“GenericDestination” para a comunicação através do weborb, a
propriedade source deve ser preenchida com o nome do projeto .NET e a
classe que será acessada, então neste caso será “ArtigoFlex.csFlex”.
A propriedade showBusyCursor seta se será
exibido ou não o relógio como cursor do mouse enquanto alguma
requisição ao .NET estiver sendo feita. E finalmente, fault define qual
função será disparada caso algum erro ocorra durante alguma requisição
do .NET.
Os métodos (
A propriedade result define qual função será disparada após o retorno da requisição ao .NET.
É necessário agora construir as funções,
faultHandler, gotRegion, gotTerritories, gotEmployee, gotCustomers,
gotOrders e gotOrderDetails. As funções são escritas na linguagem
Action Script 3.0
<mx:Script><br /> <![CDATA[<br /> import mx.rpc.events.ResultEvent;<br /> import mx.controls.Alert;<br /> import mx.rpc.events.FaultEvent;<br /> ]]><br /></mx:Script>Nesta parte do código além do bloco das
tags de inicio e fim de script, também estão declaradas as importações
das bibliotecas ResultEvent, Alert e FaultEvent que serão utilizadas
logo mais.
Agora crie a função faultHandler
private function faultHandler(event:FaultEvent):void<br />{<br /> Alert.show(event.fault.faultString, "Erro");<br />}A função faultHandler recebe um parâmetro
do tipo FaultEvent que será exibido para o usuário através do
Alert.show quando algum erro ocorrer durante a requisição ao .NET.
Agora crie os métodos de preenchimento dos valores do combobox região.
private function bindRegion():void<br />{<br /> roNet.getRegion();<br />}<br /> <br />private function gotRegion(event:ResultEvent):void<br />{<br /> cbRegion.dataProvider = event.result;<br /> cbRegion.selectedIndex = 0;<br /> bindTerritories();<br />}No código acima foram criadas duas
funções, bindRegion e gotRegion. A função bindRegion chama o método
getRegion do remote object roNet.
Após o retorno da requisição ao método
roNet.getRegion, a função gotRegion é disparada recebendo um parâmetro
do tipo ResultEvent que contém o retorno do método getRegion, o retorno
é associado como dataProvider do combobox cbRegion, em seguida é
selecionado o índice zero dos dados retornados. Após a seleção do
índice, a função bindTerritories() é disparada.
private function bindTerritories():void<br />{<br /> roNet.getTerritories(cbRegion.selectedItem.RegionID);<br />}<br /> <br />private function gotTerritories(event:ResultEvent):void<br />{<br /> cbTerritory.dataProvider = event.result;<br /> cbTerritory.selectedIndex = 0;<br /> bindEmployee();<br />}Assim como a função bindRegion,
bindTerritories chama um método do remote object roNet, porém agora o
método chamado é o getTerritories, esse método espera como parâmetro o
código da região, por isso o parâmetro informado é o
cbRegion.selectedItem.RegionID. RegionID é uma propriedade que o
dataProvider do cbRegion passou a ter após a atribuição do
event.result. Abaixo estão as demais funções para a preparação dos
comboboxs.
private function bindEmployee():void<br />{<br /> roNet.getEmployee(cbTerritory.selectedItem.TerritoryID);<br />}<br /> <br />private function gotEmployee(event:ResultEvent):void<br />{<br /> cbEmployee.dataProvider = event.result;<br /> cbEmployee.selectedIndex = 0;<br /> bindCustomers();<br />} <br /> <br />private function bindCustomers():void<br />{<br /> roNet.getCustomers(cbEmployee.selectedItem.EmployeeID);<br />}<br /> <br />private function gotCustomers(event:ResultEvent):void<br />{<br /> cbCustomer.dataProvider = event.result;<br /> cbCustomer.selectedIndex = 0;<br />}Para que quando o usuário acesse a
aplicação os comboboxs já sejam preenchidos é necessário definir a
propriedade creationComplete na tag mx:Application.
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="bindRegion()">Com essa propriedade definida, depois de
criada a aplicação, a função bindRegion será disparada iniciando assim
a população de todos os comboboxs, pois eles estão aninhados.
Também é preciso configurar os comboboxs
para que depois de alterada a seleção de um dos filtros, os outros
sejam alterados também, para isso será utilizada a propriedade change.
<mx:ComboBox y="10" id="cbRegion" labelField="RegionDescription" width="89" change="bindTerritories()" horizontalCenter="-274"></mx:ComboBox><br /><mx:ComboBox y="10" id="cbTerritory" labelField="TerritoryDescription" width="89" change="bindEmployee()" horizontalCenter="-114"></mx:ComboBox><br /><mx:ComboBox y="10" id="cbEmployee" labelField="FullName" width="89" change="bindCustomers()" horizontalCenter="49"></mx:ComboBox>Agora faça a população da datagrid,
private function bindOrders():void<br />{<br /> roNet.getOrders(cbCustomer.selectedItem.CustomerID,cbEmployee.selectedItem.EmployeeID);<br />}<br /> <br />private function gotOrders(event:ResultEvent):void<br />{<br /> dgPedido.dataProvider = event.result;<br />}Para que a função bindOrders seja disparada ao clicar o botão Consultar, defina a propriedade click do botão btConsultar.
<mx:Button y="10" label="Consultar" width="119" click="bindOrders()" horizontalCenter="310" id="btConsultar"/>Para finalizar o projeto, crie a estrutura
para exibir os detalhes dos pedidos. Para isso crie uma TitleWindow, em
File / New / MXML Component, defina o nome de orderDetails, baseado em
TitleWindow
Utilize o código abaixo para a TitleWindow orderDetails.
<?xml version="1.0" encoding="utf-8"?><br /><mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="730" height="420" title="Detalhes do Pedido" showCloseButton="true" close="{PopUpManager.removePopUp(this)}"><br /><mx:Script><br /> <![CDATA[<br /> import mx.managers.PopUpManager;<br /> import mx.events.CloseEvent;<br /> ]]><br /></mx:Script><br /><mx:DataGrid left="10" right="10" top="10" bottom="10" id="dgOrderDetails"><br /><mx:columns><br /> <mx:DataGridColumn headerText="Cód." dataField="ProductID"/><br /> <mx:DataGridColumn headerText="Produto" dataField="ProductName"/><br /> <mx:DataGridColumn headerText="Preço Un." dataField="UnitPrice"/><br /> <mx:DataGridColumn headerText="Qtde" dataField="Quantity"/><br /> <mx:DataGridColumn headerText="Desconto" dataField="Discount"/><br /> <mx:DataGridColumn headerText="Total" dataField="Total"/><br /></mx:columns><br /></mx:DataGrid> <br /></mx:TitleWindow>Crie as funções para a população da TitleWindow orderDetails dentro do script do arquivo ArtigoFlex.mxml
import mx.managers.PopUpManager;<br /> <br />public function bindOrderDetails():void<br />{<br /> roNet.getOrderDetails(dgPedido.selectedItem.OrderID);<br />}<br /> <br />private function gotOrderDetails(event:ResultEvent):void<br />{<br /> var popUp:orderDetails = orderDetails(PopUpManager.createPopUp(this, orderDetails, true));<br /> PopUpManager.centerPopUp(popUp);<br /> popUp.dgOrderDetails.dataProvider = event.result; <br />}Altere a primeira coluna da datagrid dgPedido para o código abaixo para inserir o botão para exibir os detalhes do pedido.
<mx:DataGridColumn headerText="Detalhes" width="85"><br /><mx:itemRenderer><br /><mx:Component> <br /> <mx:HBox width="100%" height="100%" horizontalAlign="center"><br /> <mx:Button y="10" width="80" label="Detalhes" click="outerDocument.bindOrderDetails()" id="btDetalhes"/><br /> </mx:HBox> <br /></mx:Component><br /></mx:itemRenderer> <br /></mx:DataGridColumn>Salve o projeto e execute, o resultado deve ser como o das figuras abaixo.


Baixe o código fonte completo.
Divirta-se.
*
Publicado originalmente em http://www.igormusardo.com.br
















