Arquivos

Archive for março \26\UTC 2010

Enviando e-mail com Flex e .net

[Atualizado em 05/04/2010]

Quando criei esse tutorial pela primeira vez, fiz apenas a parte de envio de e-mail não expliquei como se faz a integração com a aplicação .net pois não achei necessário explicar novamente sendo que já tinha postada links a respeito. Decidi adicionar a esse artigo essa parte da integração também para que não fique muito confuso.

Utilizarei para esse tutorial: Visual Studio 2008, Adobe Flex 3 e FluorineFx.dll.

Parte 1: Criando aplicação de envio de e-mail com o Visual Studio, e preparando a aplicação .net para a integração.

1.1 – Para fazer a integração de uma aplicação .net com uma aplicação Flex, utilizaremos o framework FluorineFx que é open source. Faça o download do FluorineFx aqui, não tem mistério a instalação é o básico de sempre: “Next, Next e Finish”.

1.2 – Após instalar o FlourineFx vamos criar nossa estrutura de pastas, crie uma pasta em um diretoria qualquer chamada “FlexEnviarEmail”, dentro dessa pasta crie outras três pastas chamadas: “FlexFonte”, “AspNetFonte” e “publicado”. As pastas “FlexFonte” e “AspNetFonte” serão os diretorias das aplicações do Flex e do AspNet, a pasta “publicado” será a pasta onde publicaremos a aplicação.

Estrutura de pastas FlexEnviarEmail

1.3 – Abra o VS e vá em File > New > Web Site…, escolha a pasta que você criou chamada “AspNetFonte” e “Language” C#. Renome-e o arquivo “Default.aspx” para “Gateway.aspx”. Ainda no projeto do .net, vamos agora adicionar a referencia ao framework FluorineFx, clique com o botão direito em cima da solução e em seguida clique em “Add reference…”.

Adicionando referencia há FluorineFx .net

Se você instalou corretamente o framework FlourineFx, você vai ver na lista de referencias na aba .Net o framework.

Adicionando referencia ao FluorineFx .net

Selecione o “FlourineFx for .NET Framwork 2.0”, caso sua aplicação não tenha a pasta BIN, a mesma será criada para ser adicionada essas dll’s.

Precisamos também registrar o framework FluorineFx no web.config. Então abra o web.config e adicione o seguinte código dentro do nod “configSections”:

<sectionGroup name="fluorinefx">
        <section name="settings" type="FluorineFx.Configuration.XmlConfigurator, FluorineFx"/>
</sectionGroup>

Agora dentro do nod “httpModules”:

<httpModules>
<add name="FluorineGateway" type="FluorineFx.FluorineGateway, FluorineFx"/>
</httpModules>

Muito bem, a parte de configuração do framework FluorineFx já está pronta, agora vamos fazer a aplicação para enviar o e-mail.

1.4 – Crie uma Classe chamada Email.cs (botão direito em cima do projeto > Add new item…), se o VS 2008 perguntar se você deseja criar a pasta App_Code e colocar a Classe dentro dela clique em sim. Adicione o código abaixo:

using FluorineFx;
using System.Net.Mail;

[RemotingService]
public class Email
{
    #region --- ATRIBUTOS ---
    private String nome;
    public String Nome
    {
        get { return nome; }
        set { nome = value; }
    }

    private String userMail;
    public String UserMail
    {
        get { return userMail; }
        set { userMail = value; }
    }

    private String assunto;
    public String Assunto
    {
        get { return assunto; }
        set { assunto = value; }
    }

    private String mensagem;
    public String Mensagem
    {
        get { return mensagem; }
        set { mensagem = value; }
    }
    #endregion

    public Email()
    { }

    #region --- MÉTODOS ---
    /// <summary>
    /// Envia o email.
    /// </summary>
    /// <returns>Retorna True caso dê tudo certo e false caso gere algum erro.</returns>
    public void EnviarEmail(Email _email)
    {
        MailMessage message = new MailMessage();
        SmtpClient client = new SmtpClient();

        //E-mail do rementente
        message.From = new MailAddress("email-remetente", "Remetente");
        message.IsBodyHtml = true;
        message.Body = "Nome: " + _email.nome + "<br />E-mail: " + _email.userMail + "<br />Assunto: " + _email.assunto + "<br />Mesagem: " + _email.mensagem;
        message.Subject = _email.assunto;
        //E-mail do destinatário
        message.To.Add(new MailAddress("email-destinatario", "Destinatário"));

        //E-mail e senha para enviar a mensagem
        client.Credentials = new System.Net.NetworkCredential("email-remetente/envio", "senha-email");
        //Número da porta:
        client.Port = 25;
        //Seu host para envio do e-mail
        client.Host = "host";

        client.Send(message);
        message.Dispose();
        message = null;
        client = null;
    }
    #endregion
}

As configurações de para envio de e-mail (host, porta, e-mail de envio e senha) são configurações de cada um, então não quer dizer, por exemplo, que a porta é a 25 como está no código acima, isso depende das suas configurações. Precisamos importar a FluorineFx para usar o “[RemoteService]”. O [RemoteService] que se encontra em cima da declaração da classe, serve para dizermos para o FluorineFx que essa classe será acessada remotamente pelo Flex. Criamos as propriedades nome, mail, assunto e mensagem, que são informações que pegaremos no formulário da aplicação Flex e enviaremos por e-mail. O método EnviarEmail recebe um parâmetro que é um objeto da própria classe Email (Isso ficara mais claro na aplicação Flex) e envia o e-mail.

1.5 – Agora configure a pasta “AspNetFonte” no IIS, para isso basta você clicar com o botão direito na pasta “AspNetFonte” e na aba “Compartilhamento web” escolher a opção “Compartilhar essa pasta”, na opção “alias” (apelido) coloque flexmail. Caso não tenha a aba “Compartilhamento web”, significa que seu IIS não está instalado, veja como você pode instalá-lo por esse tutorial (aconselho a trabalhar com o IIS), se você não tiver o IIS instalado, pode fazer o seguinte: O VS tem tipo um IIS interno para rodar as suas aplicações, então quando você roda uma aplicação pelo VS (apertando o F5, por exemplo) ele gera um número de porta aleatório e roda aplicação nesse servidor próprio, então a url fica mais ou menos algo assim: “http://localhost:3845/AspNetFonte/Gateway.aspx”, então rode sua aplicação e anote a url gerado no browser pois vamos precisar dela na aplicação Flex.

Pronto, já criamos nossa classe que enviara o e-mail, agora vamos para o Flex.

Parte 2: Criando formulário para envio de e-mail no Flex.

2.1 – Abra o Flex, vá em File > New > Flex Project e selecione a pasta FlexFonte que você criou anteriormente, coloque um nome qualquer para o projeto (no caso eu coloquei o mesmo nome da pasta) e clique em finish. Crie uma pasta dentro da pasta src com o nome de classes, agora adicionamos uma arquivo ActionScript Class com o nome de Email dentro dessa pasta (botão direito na pasta classes > new > actionscript class). Essa classe precisa ter exatamente o mesmo nome da classe na aplicação .net (no caso Email), então ela deve se chamar “Email.as”. Adicione o código abaixo nessa classe:

package classes{
	[RemoteClass(alias="Email")]
	public class Email{
		private var nome:String;
		public function get Nome():String{
			return nome;
		}
		public function set Nome(n:String):void{
			this.nome = n;
		}

		private var mail:String;
		public function get Mail():String{
			return mail;
		}
		public function set Mail(m:String):void{
			this.mail = m;
		}

		private var assunto:String;
		public function get Assunto():String{
			return assunto;
		}
		public function set Assunto(a:String):void{
			this.assunto = a;
		}

		private var mensagem:String;
		public function get Mensagem():String{
			return mensagem;
		}
		public function set Mensagem(msg:String):void{
			this.mensagem = msg;
		}

		public function Email(){
		}
	}
}

Assim como na classe da aplicação .net, no Flex também precisamos dizer qual é a classe remota que ele irá acessar, por isso inserimos o [RemoteClass(alias=”Email”)] no começo da classe. A classe “Email” que está setado no “alias=”, é a classe “Email.cs” da aplição .net. Note que até mesmo o nome das propriedades tem que ser o mesmo do que a classe “Email.cs”. O get e set do actionscript 3.0 é bem semelhando ao do .net como podemos reparar.

2.2 – Dentro do arquivo principal do Flex, adicione o código abaixo:

<mx:RemoteObject id="roMail" source="Email" destination="fluorine" showBusyCursor="true">
		<mx:method name="EnviarEmail" result="{resultadoEnviar(event)}" fault="{falhaEnviar(event)}"/>
	</mx:RemoteObject>

	<mx:VBox height="384" width="300" horizontalCenter="0" verticalCenter="0">
		<mx:TextInput id="txtNome" focusIn="removeTextoPadrao(this.txtNome)" focusOut="addTextoPadrao(this.txtNome)" text="Nome"/>
		<mx:TextInput id="txtEmail" width="280" focusIn="removeTextoPadrao(this.txtEmail)" focusOut="addTextoPadrao(this.txtEmail)" text="E-mail"/>
		<mx:ComboBox id="comboAssunto" creationComplete="preencheCombo()"></mx:ComboBox>
		<mx:TextArea width="300" height="120" id="txtMensagem" focusIn="removeTextoPadraoTextArea(this.txtMensagem)" focusOut="addTextoPadraoTextArea(this.txtMensagem)" text="Mensagem"/>
		<mx:Button label="Enviar" id="btnEnviar" click="enviarEmail(event)"/>
	</mx:VBox>

O “mx:RemoteObject” serve para se conectar remotamente com a classe “Email.cs”, especificamos qual classe ele ira se conectar através da propriedade “source”. A propriedade “showBusyCursor=true” serve para que enquanto o RemoteObject estiver sendo executado será exibido um cursor de carregando (tipo a ampulheta do windows).

Na tag mx:Method dizemos qual o método iremos usar da classe “Email.cs” pela propriedade “name” (pode se ter varias tags mx:Method para os métodos da classe), a propriedade “result” indica qual função será executada caso dê tudo certo na execução do método da classe “Email.cs”, caso dê algo errado, será executada a função que está registrada na propriedade “fault” (criaremos essas funções mais a frente). Em alguns controles pode-se observar que existem funções ligadas aos eventos focusIn (evento disparado quando o focu está no controle) e focusOut (evento disparado quando o focu sai do controle), que veremos no próximo passo.

2.3 – Crie um bloco “mx:Script” logo acima do código que você adicionou anteriormente, depois adicione esse código ao script:

import mx.rpc.remoting.mxml.RemoteObject;
import mx.rpc.events.ResultEvent;
import mx.rpc.events.FaultEvent;
import mx.controls.Alert;
import classes.Email;
import mx.collections.ArrayCollection;

/********** EVENTOS DOS CONTROLES DO FORMULÁRIO **********/
			//Preenche o combo box com as opções de assunto
			private function preencheCombo():void{
				var lista:ArrayCollection = new ArrayCollection();
				lista.addItem("Selecione --");
				lista.addItem("Dúvida");
				lista.addItem("Sugestão");
				lista.addItem("Reclamação");
				comboAssunto.dataProvider = lista;
			}

			//Retira o texto padrão dos inputs nome e email
			private function removeTextoPadrao(t:TextInput):void{
				if (t.text == "Nome" || t.text == "E-mail")
					t.text = "";
			}

			//Adiciona o texto padrão dos inputs nome e email
			private function addTextoPadrao(t:TextInput):void{
				if (t.id == "txtNome" && t.text == "")
					t.text = "Nome";
				else if (t.id == "txtEmail" && t.text == "")
					t.text = "E-mail";
			}

			//Remove texto padrão do textarea
			private function removeTextoPadraoTextArea(ta:TextArea):void{
				if (ta.text == "Mensagem")
					ta.text = "";
			}

			//Adiciona texto padrão do textarea
			private function addTextoPadraoTextArea(ta:TextArea):void{
				if (ta.text == "")
					ta.text = "Mensagem";
			}

			//Volta com todos os textos padrões
			private function textoPadrao():void{
				txtNome.text = "Nome";
				txtEmail.text = "E-mail";
				txtMensagem.text = "Mensagem";
				comboAssunto.selectedIndex = 0;
			}

/********** FUNÇÕES DE CONECXÃO COM A APLICAÇÃO .NET **********/
			//Função que é executada se ocorreu algum erro ao enviar o e-mail
			private function falhaEnviar(evt:FaultEvent):void{
		    	Alert.show("Ocorreu o seguinte erro ao tentar executar o método:\n" + evt.fault.message, "Erro");
			}

			//Função que é executada se não ocorreu erros no envio de e-mail
			private function resultadoEnviar(evt:ResultEvent):void{
	        	textoPadrao();
	        	Alert.show("E-mail enviado com sucesso!");
		    }

			//Função que é acionado com o clique do mouse
			private function enviarEmail(evt:MouseEvent):void{
		    	if (evt.type == MouseEvent.CLICK){
		        	var email:Email = new Email;
		        	email.Nome = txtNome.text;
		        	email.Mail = txtEmail.text;
		        	email.Assunto = comboAssunto.selectedLabel;
		        	email.Mensagem = txtMensagem.text;
		        	roMail.getOperation("EnviarEmail").send(email);
		    	}
			}

A função “preencheCombo” serve para preencher o comboBox assunto, com informações de um arrayCollection. As funções que seguem abaixo da função “preencheCombo” servem somente para retirar ou adicionar texto padrão nos inputs. A função “textoPadrao” serve para retornar os textos padrões para os inputs depois que o e-mail for enviado. A função “falhaEnviar” que recebe como parâmetro um “FaultEvet” é a função que será executada caso ocorra algum erro na execução do RemoteObject, e a função “resultadoEnviar” será disparada caso ocorra tudo bem, perceba que as duas funções simplesmente executam um “Alert” informando o que aconteceu.

A função “enviarEmail” é executada quando clicamos no botão “btnEnviar” (o evento clique chama a função enviarEmail) e dentro dessa função, criamos um objeto da classe “Email.as” e preenchemos os atributos com os valores do formulário. Para executar o método que está registrado no “roMail” (id do mx:RemoteObject), executamos o “getOperation” do “roMail” e passamos como parâmetro o nome do método registrado, em seguida executamos o send(). Como já sabemos, o método “EnviarEmail” da classe “Email.cs” espera um parâmetro do tipo “Email”, então no “send()” do “getOperation” passamos o objeto da classe “Email.as” que criamos com os dados do formulário(“.send(email)”). Caso o método “EnviarEmail” da classe “Email.cs” não esperasse nenhum parâmetro, bastava executar o “send()” sem parâmetros mesmo.

Parte 3: Configurando a aplicação Flex para se conectar com a aplicação .net.

3.1 – Clique com o botão direito na pasta src e selecione File > New > File, coloque o nome do arquivo de “services-config.xml”, é com esse arquivo que faremos o mapeamento das classes ActioScript com .Net/C#. Adicione o código abaixo nesse arquivo:

<?xml version="1.0" encoding="UTF-8"?>
    <services-config>
        <services>
            <service id="remoting-service"
            class="flex.messaging.services.RemotingService"
            messageTypes="flex.messaging.messages.RemotingMessage">
                <destination id="fluorine">
                    <channels>
                        <channel ref="my-amf"/>
                    </channels>
                    <properties>
                        <source>*</source>
                    </properties>
                </destination>
            </service>
        </services>
        <channels>
        <channel-definition id="my-amf"
        class="mx.messaging.channels.AMFChannel">
            <endpoint uri="http://localhost/flexmail/Gateway.aspx"
            class="flex.messaging.endpoints.AMFEndpoint"/>
        </channel-definition>
    </channels>
</services-config>

Se você configurou a aplicação .net no IIS, coloque a url da aplicação na opção “uri” do nod “endpoint” (como você pode observar, a url que está no código acima é uma url de uma aplicação que está configurada no IIS), caso você não esteja usando o IIS e sim o VS, então coloque a url gerada pelo VS (passo 1.5) e adicione no “uri” do nod “endpoint”. Agora clique com o botão direito em cima da aplicação Flex e clique em properties:

Na opção “Flex Compiler” adicione o texto “-services services-config.xml” no “Additional compiler arguments”:

Deixe um espaço em branco entre o “-locale en_US” e o “-services services-config.xml”. Agora já está tudo ok, já da para testar a aplicação, se você conseguiu configurar a aplicação no IIS, basta executar a aplicação no Flex e já estará tudo funcionando. Caso você tenha usado a url gerado pelo VS, você terá que executar a aplicação .net primeiro, e depois executar a aplicação Flex, é preciso fazer isso para que o VS inicie o seu servidor interno.

Parte 4: Publicando as aplicações.

4.1 – Para isso você precisara do IIS instalado, primeiro vamos publicar a aplicação .net, abra o VS e abra a aplicação que esta na pasta “AspNetFonte”, clique com o botão direito na solução e clique em “Publish Web Site”:

clique no botão “…” e selecione a pasta que você criou chamada “publicado”, deixe apenas a opção “Allow this precompiled site to be updatable” marcada e clique em ok.

Pronto, a aplicação .net está publicada, agora vamos publicar a aplicação Flex. Abra a aplicação Flex, depois abra o arquivo services-config.xml, e na opção “uri” do nod “endpoint”, deixe assim:

<endpoint uri="Gateway.aspx" class="flex.messaging.endpoints.AMFEndpoint"/>

Isso por que toda a pasta publicado será uma aplicação, e a aplicação Flex e .net estarão na mesma pasta, então não é preciso colocar o caminho completo da aplicação. Agora selecione o projeto Flex, clique no botão superior Project > Export Release Build…:

Na opção “Browser” selecione a pasta “publicado” e clique em Finish. Agora configure a pasta “publicado” no IIS, agora é só acessar a aplicação no seu localhost e pronto.

Baixe o projeto aqui, até a próxima!

CategoriasTutoriais Tags:, , , ,

Preenchendo ComboBox e List com dados de um banco (Flex + .net)

Nesse tutorial vou mostrar como preencher um controle ComboBox do Flex com dados de um banco, e preencher um controle List de acordo com o dado que foi selecionado no controle ComboBox. Para isso vou usar o Visual Studio 2008 com c#, Sql Server 2005 com o banco Northwind, Adobe Flex 3 e actionscript 3.0. Como citei no post anterior (Flex e .net – dicas, links e tutoriais), todos os artigos que eu escrever que terão a integração de Flex com .net, criarei com base no artigo que se encontra na minha lista de links (Flex + .net).

1 – Vamos começar criando a aplicação no Visual Studio 2008, File > New > Web Site. Coloquei o nome de “pcAspNet”, pois a aplicação que vou criar no Adobe Flex se chamará “PreencheControles”. Vamos criar uma classe chamada Selecao, dentro dela vamos importar a ddl FluorineFx para a integração das aplicações, e acima da classe Selecao colocar [RemotingService] (a estrutura da aplicação é semelhante à aplicação que se encontra no link que se está na minha lista de links, e tudo que citei anteriormente também é explicado lá).

2 – Agora vamos adicionar uma string de conexão com o banco no web.config (claro que, essa configuração é baseada no meu servidor de banco, adapte a mesma para o seu banco).

<add name="NorthwindConn" connectionString="Data Source=RICARDO-FC13DCB\SQLEXPRESS;Initial Catalog=Northwind;User ID=sa;Password=server" providerName="System.Data.SqlClient" />

3 – Agora vamos adicionar os métodos que retornaram os dados para a aplicação Flex:

public ArrayList SelecionaCategorias()
    {
        ArrayList lista = new ArrayList();
        try
        {
            SqlConnection Conn = new SqlConnection(GetConnectionString());
            Conn.Open();
            SqlCommand Comm = new SqlCommand("SELECT CategoryName FROM Categories", Conn);
            SqlDataReader Reader = Comm.ExecuteReader();
            while (Reader.Read())
            {
                lista.Add(Reader.GetValue(0).ToString());
            }
        }
        catch (Exception ex)
        { }
        return lista;
    }

    public ArrayList SelecionaProdutos(String CategoryName)
    {
        ArrayList lista = new ArrayList();
        try
        {
            SqlConnection Conn = new SqlConnection(GetConnectionString());
            Conn.Open();
            SqlCommand Comm = new SqlCommand("SELECT  P.ProductName FROM Products AS P INNER JOIN Categories AS C ON P.CategoryID = C.CategoryID WHERE (C.CategoryName = '" + CategoryName + "')", Conn);
            SqlDataReader Reader = Comm.ExecuteReader();
            while (Reader.Read())
            {
                lista.Add(Reader.GetValue(0).ToString());
            }
        }
        catch (Exception ex)
        { }
        return lista;
    }

    private String GetConnectionString()
    {
        return ConfigurationManager.ConnectionStrings["NorthwindConn"].ConnectionString;
    }

Para usar o ArrayList, precisamos importar a classe Collections (using System.Collections;).O primeiro método retorna um ArrayList contendo o nome de todas as categorias, o segundo, retorna o nome de todos os produtos de acordo com o nome de uma categoria especifica. E o terceiro serve simplesmente para retornar a string de conexão que se encontra no web.config.

4 – Agora vamos para o Adobe Flex, crie um novo projeto File > New > Flex Project, configure-o em um diretório que você queira, e coloque o nome dele de PreenchendoControles. IMPORTANTE: Após fazer toda a configuração necessário no Flex para a integração entre as aplicações (veja o link na lista de links), configure a aplicação pcAspNet no IIS e coloque o endereço da mesma no arquivo “service-config.xml”.

5 – Adicione os controles ComboBox e List no Flex, com os id’s: comboCategorias e listProdutos. Adicione também o controle RemoteObject como no código abaixo:

<mx:RemoteObject id="ro" source="Selecao"
     destination="fluorine" showBusyCursor="true">        
        <mx:method name="SelecionaCategorias"
        result="{AddCategorias(event)}" fault="{errorFault(event)}"/>
        <mx:method name="SelecionaProdutos"
        result="{AddProdutos(event)}" fault="{errorFault(event)}"/>
    </mx:RemoteObject>

    <mx:ComboBox id="comboCategorias" change="ro.SelecionaProdutos(comboCategorias.selectedLabel)" creationComplete="{ro.SelecionaCategorias()}" y="10" width="200" x="121"></mx:ComboBox>	
	<mx:List id="listaProdutos" x="329" y="9" width="200" height="150"></mx:List>

Como já sabemos, a propriedade source do RemoteObject precisa ser setada com o nome da classe que criamos no pcAspNet (Selecao), nas tag method, são configurados os métodos da classe Selecao. IMPORTANTE: No ComboBox tem um evento chamado creationComplete, esse evento é disparado assim que o ComboBox é renderizado na tela, então assim não corremos o risco de preencher os dados do ComboBox antes de ele ser criado na tela. No evento change, que o evento que é disparado toda a vez que muda a seleção no ComboBox, coloquei o método que preencherá o List com a lista de produtos toda a vez que o valor do ComboBox for alterado.

6 – Agora vamos criar o bloco de script que terá os métodos que preencheram os controles:

<mx:Script>
    <![CDATA[
        import mx.controls.Alert;
        import mx.rpc.events.ResultEvent;
        import mx.rpc.events.FaultEvent;
        import mx.collections.ArrayCollection;
        
        private function errorFault(evt:FaultEvent):void
        {
            Alert.show(evt.fault.faultString);
        }
        
        private function AddCategorias(e:ResultEvent):void
        {        	
        	var lista:ArrayCollection = e.result as ArrayCollection;
        	lista.addItemAt("Selecione --", 0);
        	comboCategorias.dataProvider = lista;        	   
        }
        
        private function AddProdutos(e:ResultEvent):void
        {
        	var lista:ArrayCollection = e.result as ArrayCollection;        	
        	listaProdutos.dataProvider = lista; 
        }

        ]]>
    </mx:Script>

Precisamos importar as classes acima para poder trabalhar. O método errorFault é chamado somente se acontece algum erro, o AddCategorias é o método que preencherá o controle ComboBox: Criamos uma variável do Tipo ArrayCollection que receberá o ArrayList do c# com os nomes das categorias, depois adicionamos um item a mais na posição “0”. E no final definimos o ArrayCollection com sendo o dataProvider do ComboBox. No AddProduto fazemos praticamente a mesma coisa, só não adicionamos nada na primeira posição.

E pronto, sem mistério, agora é só rodar a aplicação e você preencherá o List somente quando selecionar uma opção no ComboBox.

Segue o arquivo para download. Até a próxima!

CategoriasTutoriais Tags:, , ,

Flex e .net – dicas, links e tutoriais

Fiquei muito tempo sem atualizar o blog, o motivo principal foi a falta de tempo mesmo. Alem de trabalhar com desenvolvimento web, principalmente com .net, tenho estudado muito sobre o Adobe Flex e actionscritp 3.0 e a integração deles com .net, a partir de hoje pretendo colocar tudo que eu aprender a respeito e algumas experiências que eu fizer. Nesse post irei colocar links bastante úteis que encontrei nas minhas buscas.

Links:

Twitter:

Além de vários conteúdos que eu achei na internet, estou lendo um livro que se chama: Adobe Flex 3 Treinamento Direto da Fonte (http://www.livrariasaraiva.com.br/produto/2657203/adobe-flex-3-treinamento-direto-da-fonte/?ID=BB49E13C7DA03150E30210590), é um livro muito bom, caso você realmente esteja interessando em aprender Flex, eu recomendo esse livro.

Bom, é isso, até a próxima!

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.