ASP .NET - Gerador de Cartões (revisão Web Forms para novatos)
Neste artigo eu vou criar um gerador de cartões usando ASP .NET e a tecnologia Web Forms. O objetivo é rever alguns conceitos básicos para quem esta iniciando no aprendizado ASP .NET.
É importante lembrar que a plataforma .NET além da ASP .NET possui também a tecnologia ASP .NET MVC que proporciona uma nova abordagem que permite um controle maior do desenvolvedor sobre a aplicação web.
Neste exemplo vamos usar alguns controles ASP .NET Web Forms básicos e veremos como tratar os eventos e a manipular os controles com suas propriedades básicas tudo isso criando uma aplicação simples que você poderá depois incrementar se assim o desejar.
Neste artigo você vai aprender a :
Requisitos:
Objetivos
Criar um gerador de cartões com opções para o usuário definir cor de fundo, fonte, tamanho da fonte, estilo da borda, imagem e texto.
Criando o projeto no Visual Studio 2012 Express for web
Abra o Visual Studio 2012 Express for web e clique em New Project;
A seguir selecione o template Visual C# -> Web -> ASP .NET Empty Web Application, informe o nome GeradorDeCartoes e clique em OK;
O template usado cria um projeto contendo apenas a estrutura básica sem nenhuma página.
A seguir no menu PROJECT clique em Add New Item e selecione o template Web Form informando o nome Default.aspx e clicando no botão Add;
Agora no clique com o botão direito do mouse sobre o nome do projeto e selecione Add -> New Folder e informe o nome Imagens. Criamos assim uma pasta chamada Imagens para guardar as imagens usadas nos cartões.
Clique com o botão direito do mouse sobre a pasta Imagens e selecione Add-> Existing Item e selecione as imagens que serão armazenadas nesta pasta.
Vamos definir o código da página Default.aspx, para isso selecione o arquivo Default.aspx, na janela Solution Explorer, e a seguir no descritor, clique na aba Source e inclua o código abaixo neste arquivo:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GeradorDeCartoes.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Gerador de Cartões</title> </head> <body> <form id="form1" runat="server"> <div style="BORDER-RIGHT: thin ridge; PADDING-RIGHT: 20px; BORDER-TOP: thin ridge; PADDING-LEFT: 20px; FONT-SIZE: x-small; PADDING-BOTTOM: 20px; BORDER-LEFT: thin ridge; WIDTH: 295px; PADDING-TOP: 20px; BORDER-BOTTOM: thin ridge; FONT-FAMILY: fantasy; HEIGHT: 490px; BACKGROUND-COLOR: lightyellow"> <!-- Controles do formulário: --> Escolha uma cor de fundo:<br /> <asp:DropDownList ID="lstCorDeFundo" runat="server" Width="194px" Height="22px"/><br /><br /> Escolha a fonte:<br /> <asp:DropDownList ID="lstNomeDaFonte" runat="server" Width="194px" Height="22px" /><br /><br /> Defina o tamanho da fonte:<br /> <asp:TextBox ID="txtTamanhoDaFonte" runat="server" >10</asp:TextBox> <br /><br /> Escolha um estilo de borda:<br /> <asp:RadioButtonList ID="lstBorda" runat="server" Width="177px" Height="59px" /><br /> Escolha uma Imagem :<br /> <asp:DropDownList ID="lstImagem" runat="server" Width="194px" Height="22px" OnSelectedIndexChanged="lstImagem_SelectedIndexChanged" /><br /><br /> <asp:CheckBox ID="chkImagem" runat="server" Text="Exibir Imagem"></asp:CheckBox><br /><br /> Digite o texto do cartão abaixo:<br /> <asp:TextBox ID="txtTexto" runat="server" Width="240px" Height="85px" TextMode="MultiLine" >Seu Texto aqui</asp:TextBox> <br /><br /> <asp:Button ID="cmdAtualiza" OnClick="cmdAtualiza_Click" runat="server" Width="71px" Height="24px" Text="Atualizar" /> </div> <!-- Aqui esta o cartão: --> <asp:panel ID="pnlCartao" style="LEFT: 350px; POSITION: absolute; TOP: 16px; height: 528px;" runat="server" Width="340px" HorizontalAlign="Center"><br /> <asp:Label ID="lblTexto" runat="server" Width="256px" Height="150px" /><br /><br /><br /> <asp:Image ID="imgDefault" runat="server" Width="259px" Height="217px" /> </asp:panel> </form> </body> </html> |
A página web esta dividida em duas regiões. À esquerda, há uma tag <div> comum contendo um conjunto de controles Web para especificar as opções do cartão. À direita está um controle Panel (chamado pnlCartao), que contém dois outros controles (lblTexto e imgDefault) que são usados para exibir o texto configurável pelo usuário e uma imagem. Este texto e imagem representa o cartão. Quando a página for carregada pela primeira vez, o cartão ainda não será gerado, e a parte direita estará em branco conforme vemos na figura abaixo:
Para obter o
layout de duas colunas neste exemplo, temos duas
escolhas: 1- usar tabelas HTML (que são uma técnica um tanto antiquada) 2- usar o posicionamento absoluto com estilos CSS (como neste exemplo). O posicionamento absoluto é fácil de entender. Basta olhar para o atributo de estilo no painel de controle, o que especifica uma coordenada superior e esquerda fixa na página web. Quando o painel for processado para HTML, este ponto torna-se seu canto superior esquerdo. |
O elemento <div> é útil quando você quiser agrupar texto e controles e aplicar um conjunto de propriedades de formatação (tal como uma cor ou fonte) a todos eles. O elemento <div> também é uma ferramenta essencial para os blocos de posicionamento do conteúdo de uma página.
Sempre que o usuário clicar no botão Atualizar a página sofre um postback e o cartão é atualizado.
Vamos preencher os controles usando o código no arquivo Default.aspx.cs. Vamos tratar com os seguintes eventos:
O código code-behind do arquivo Default.aspx.cs é visto abaixo:
using System; using System.Web.UI.WebControls; using System.Drawing; namespace GeradorDeCartoes { public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!this.IsPostBack) { // define as opções de cores lstCorDeFundo.Items.Add("White"); lstCorDeFundo.Items.Add("Red"); lstCorDeFundo.Items.Add("Green"); lstCorDeFundo.Items.Add("Blue"); lstCorDeFundo.Items.Add("Yellow"); // define as opções de fonte lstNomeDaFonte.Items.Add("Times New Roman"); lstNomeDaFonte.Items.Add("Arial"); lstNomeDaFonte.Items.Add("Verdana"); lstNomeDaFonte.Items.Add("Tahoma"); // define imagens lstImagem.Items.Add("feliz"); lstImagem.Items.Add("aniversario1"); lstImagem.Items.Add("aniversario2"); lstImagem.Items.Add("anonovo1"); lstImagem.Items.Add("anonovo2"); lstImagem.Items.Add("maes1"); lstImagem.Items.Add("maes2"); lstImagem.Items.Add("namorados1"); lstImagem.Items.Add("namorados2"); lstImagem.Items.Add("pais1"); lstImagem.Items.Add("pais2"); lstImagem.Items.Add("amigos"); lstImagem.Items.Add("amizade"); lstImagem.SelectedIndex = -1; // Define o estilo da borda adicionando uma série de objetos ListItem ListItem item = new ListItem(); // O texto Item indica o nome da opção item.Text = BorderStyle.None.ToString(); // O valor do item registra o inteiro correspondente // a partir da enumeração. Para obter este valor você // precisa dar um cast no valor da enumeração para integer // e então converter o numero para uma string para ser colocada na pagina HTML item.Value = ((int)BorderStyle.None).ToString(); // Adicona um item lstBorda.Items.Add(item); // repete o processo para as mais dois estilos de bordas item = new ListItem(); item.Text = BorderStyle.Double.ToString(); item.Value = ((int)BorderStyle.Double).ToString(); lstBorda.Items.Add(item); item = new ListItem(); item.Text = BorderStyle.Solid.ToString(); item.Value = ((int)BorderStyle.Solid).ToString(); lstBorda.Items.Add(item); // Selecina o primeira opção da borda lstBorda.SelectedIndex = 0; // Defina a imagem atualizaImagem(); } } protected void cmdAtualiza_Click(object sender, EventArgs e) { // Atualiza a cor pnlCartao.BackColor = Color.FromName(lstCorDeFundo.SelectedItem.Text); // atualiza fonte lblTexto.Font.Name = lstNomeDaFonte.SelectedItem.Text; if (Int32.Parse(txtTamanhoDaFonte.Text) > 0) { lblTexto.Font.Size = FontUnit.Point(Int32.Parse(txtTamanhoDaFonte.Text)); } // Atualiza o estilo da borda // convertemos o valor do item da lista de uma string em um inteiro // e depois convertemos esse valor para a enumeração BorderStyle int borderValue = Int32.Parse(lstBorda.SelectedItem.Value); pnlCartao.BorderStyle = (BorderStyle)borderValue; lblTexto.Text = txtTexto.Text; atualizaImagem(); } protected void lstImagem_SelectedIndexChanged(object sender, EventArgs e) { //chama a rotina para atualizar a fonte atualizaImagem(); } protected void atualizaImagem() { //verifica se é para exibir a imagem if (chkImagem.Checked) { //obtem a imagem selecionada e exibe if (lstImagem.SelectedIndex != -1) { string nomeImagem = lstImagem.SelectedItem.Text + ".jpg"; imgDefault.ImageUrl = @"~/Imagens/" + nomeImagem; imgDefault.Visible = true; } } else { //não exibe a imagem imgDefault.Visible = false; } } } } |
Note que definimos a rotina atualizaImagem() que verifica se a imagem deve ser exibida e obtém o valor selecionado da dropdownlist de imagens montando o nome da imagem e exibindo-a no controle image imgDefault usando a propriedade ImageUrl.
Abaixo vemos o cartão montado e exibido com as opções selecionadas na página Default.aspx:
No evento Load da página verificamos se não esta ocorrendo um postback (!this.IsPostBack) e preenchemos os controles lstCorDeFundo, lstNomeDaFonte e lstImagem com valores pré-definidos.
Como você pode ver, este exemplo limita o usuário a escolher algumas fontes e cores pré-definidas no código.
O código para a opção BorderStyle é interessante. O controle lstBorda tem uma lista que exibe o nome do texto de um dos valores da enumeração BorderStyle, cada valor enumerado é um inteiro com um nome atribuído a ele. O lstBorda também armazena o número correspondente para que o código possa recuperar o número e definir a enumeração quando o usuário faz uma seleção e o evento cmdAtualizar_Click for disparado.
Melhorando o gerador de cartões
Nosso gerador de cartões esta funcional mas pode ser melhorado. Qualquer alteração feita pelo usuário somente será efetivada se o botão Atualizar for clicado. Vamos tornar o processo de gerar os cartões mais automático.
Vamos incluir também uma nova dropdownlist permitindo que o usuário selecione a cor da fonte. O código para isso é o seguinte:
Escolha a
cor da fonte:<br />
<asp:dropdownlist ID="lstCorDaFonte"
runat="server" Height="22px"
Width="194px" AutoPostBack="True"
onselectedindexchanged="ControlChanged"></asp:dropdownlist><br
/><br />
Outro ponto que podemos melhorar é preencher os controles para as fontes e nome das fontes a partir das fontes instaladas no sistema ao invés de definirmos isso no código com algumas poucas opções.
Assim podemos preencher o controle lstNomeDaFonte com uma lista das fontes instaladas usando a classe InstalledFontCollection conforme o código a seguir:
InstalledFontCollection fontes = new InstalledFontCollection(); foreach (FontFamily familia in fontes.Families) { lstNomeDaFonte.Items.Add(familia.Name); } |
Para obter uma lista dos nomes das cores, é preciso recorrer a um truque mais avançado. Embora você possa codificar uma lista de cores usando a enumeração System.Drawing.KnownColor. No entanto extrair os nomes a partir desta enumeração dá algum trabalho.
O truque é usar uma característica básica de todas as enumerações. O método estático Enum.GetNames(), que inspeciona uma enumeração e fornece um array de strings, com uma string para cada valor na enumeração. A página web pode, então, usar o databinding para preencher automaticamente o controle de lista com a informação no array de cores. Abaixo temos o código que faz isso:
string[] borderStyleArray = Enum.GetNames(typeof(BorderStyle)); lstBorda.DataSource = borderStyleArray; lstBorda.DataBind(); |
Este código gera um novo desafio: como vamos converter o valor que o usuário seleciona para o a constante apropriada para a enumeração ?
Quando o usuário escolhe um estilo de borda da lista, a propriedade SelectedItem terá uma cadeia de texto como "Groove". Mas, para aplicar este estilo de borda para o controle, você precisa encontrar uma maneira de determinar a constante enumerada que corresponde a este texto.
Neste caso, a abordagem mais direta é usar um recurso avançado chamado TypeConverter. Um TypeConverter é uma classe especial que é capaz de converter de uma forma especializada (neste caso, a enumeração BorderStyle) para um tipo mais simples (como uma string), e vice-versa. Para acessar esta classe, você precisa importar o namespace System.ComponentModel:
using System.ComponentModel; // Encontra o apropriado TypeConverter para a enumeração BorderStyle TypeConverter converter = TypeDescriptor.GetConverter(typeof(BorderStyle));
// atualiza o estilo da borda usando o valor a partir do converter. |
Este código obtém o TypeConverter adequado (neste caso, um que é concebido para funcionar com a enumeração BorderStyle). Em seguida, ele converte o nome de texto (como Solid) para o valor apropriado (BorderStyle.Solid).
O último passo é usar eventos postback automático da ASP.NET para fazer a atualização do cartão de forma dinâmica cada vez que uma opção for alterada. O botão Atualizar, agora poderia ser usado para enviar a versão final do cartão por email para um destinatário, ou acionar uma rotina para armazenar o cartão em um banco de dados.(fica a seu critério definir o que deseja fazer...)
Para configurar os controles de forma que eles acionem automaticamente uma postagem da página quando ocorrer qualquer alteração em um evento basta definir a propriedade AutoPostBack de cada controle de entrada para true.
Obs: Autopostback é o mecanismo pelo qual a página será postada de volta para o servidor automaticamente com base em alguns eventos nos controles do formulário web. Em alguns destes controles, se definirmos a propriedade AutoPostBack igual a true, a requisição será enviada para o servidor quando um evento ocorrer no controle.
A seguir vamos altear as tags dos controles de forma que a mudança do evento para cada controle seja vinculada para um tratamento de evento chamado ControlChanged que iremos definir depois no código.
Abaixo temos a versão final do arquivo Default.aspx com as novas implementações:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GeradorDeCartoes.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Gerador de Cartões</title> </head> <body> <form id="form1" runat="server"> <div style="BORDER-RIGHT: thin ridge; PADDING-RIGHT: 20px; BORDER-TOP: thin ridge; PADDING-LEFT: 20px; FONT-SIZE: x-small; PADDING-BOTTOM: 20px; BORDER-LEFT: thin ridge; WIDTH: 295px; PADDING-TOP: 20px; BORDER-BOTTOM: thin ridge; FONT-FAMILY: fantasy; HEIGHT: 490px; BACKGROUND-COLOR: lightyellow"> <!-- Controles do formulário: --> Escolha uma cor de fundo:<br /> <asp:DropDownList ID="lstCorDeFundo" runat="server" AutoPostBack="True" onselectedindexchanged="ControlChanged" Width="194px" Height="22px"/><br /><br /> Escolha a cor da fonte:<br /> <asp:dropdownlist ID="lstCorDaFonte" runat="server" Height="22px" Width="194px" AutoPostBack="True" onselectedindexchanged="ControlChanged"> </asp:dropdownlist><br /><br /> Escolha a fonte:<br /> <asp:DropDownList ID="lstNomeDaFonte" runat="server" AutoPostBack="True" onselectedindexchanged="ControlChanged" Width="194px" Height="22px" /><br /><br /> Defina o tamanho da fonte:<br /> <asp:TextBox ID="txtTamanhoDaFonte" runat="server" AutoPostBack="True" ontextchanged="ControlChanged" >10</asp:TextBox> <br /><br /> Escolha um estilo de borda:<br /> <asp:RadioButtonList ID="lstBorda" runat="server" AutoPostBack="True" onselectedindexchanged="ControlChanged" RepeatColumns="2" Width="177px" Height="59px" /><br /> Escolha uma Imagem :<br /> <asp:DropDownList ID="lstImagem" runat="server" AutoPostBack="True" Width="194px" Height="22px" OnSelectedIndexChanged="ControlChanged" /><br /><br /> <asp:CheckBox ID="chkImagem" runat="server" AutoPostBack="True" oncheckedchanged="ControlChanged" Text="Exibir Imagem"></asp:CheckBox><br /><br /> Digite o texto do cartão abaixo:<br /> <asp:TextBox ID="txtTexto" runat="server" AutoPostBack="True" ontextchanged="ControlChanged" Width="240px" Height="85px" TextMode="MultiLine" >Seu Texto aqui</asp:TextBox> <br /><br /> <asp:Button ID="cmdAtualiza" OnClick="cmdAtualiza_Click" runat="server" Width="71px" Height="24px" Text="Atualizar" /> </div> <!-- Aqui esta o cartão: --> <asp:panel ID="pnlCartao" style="LEFT: 350px; POSITION: absolute; TOP: 16px; height: 528px;" runat="server" Width="340px" HorizontalAlign="Center"><br /> <asp:Label ID="lblTexto" runat="server" Width="256px" Height="150px" /><br /><br /><br /> <asp:Image ID="imgDefault" runat="server" Width="259px" Height="217px" /> </asp:panel> </form> </body> </html> |
Note que o nome do evento Changed vai depender do controle. Assim a caixa de texto proporciona um evento TextChanged, o ListBox fornece um evento SelectedIndexChanged, e assim por diante.
Finalmente, você precisa criar um manipulador de eventos que possa lidar com os eventos de mudança. Podemos usar o mesmo manipulador de evento para todos os controles de entrada. Todo o manipulador de evento precisa vincular a rotina de atualização que regenera o cartão.
O novo código do code-behind em Default.aspx.cs é visto abaixo:
using System; using System.Web.UI.WebControls; using System.Drawing; using System.Drawing.Text; using System.ComponentModel; namespace GeradorDeCartoes { public partial class Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (!this.IsPostBack) { // Pega a lista de cores string[] colorArray = Enum.GetNames(typeof(KnownColor)); lstCorDeFundo.DataSource = colorArray; lstCorDeFundo.DataBind(); //define a cor da fonte lstCorDaFonte.DataSource = colorArray; lstCorDaFonte.DataBind(); lstCorDaFonte.SelectedIndex = 34; lstCorDaFonte.SelectedIndex = 163; // define imagens lstImagem.Items.Add("feliz"); lstImagem.Items.Add("aniversario1"); lstImagem.Items.Add("aniversario2"); lstImagem.Items.Add("anonovo1"); lstImagem.Items.Add("anonovo2"); lstImagem.Items.Add("maes1"); lstImagem.Items.Add("maes2"); lstImagem.Items.Add("namorados1"); lstImagem.Items.Add("namorados2"); lstImagem.Items.Add("pais1"); lstImagem.Items.Add("pais2"); lstImagem.Items.Add("amigos"); lstImagem.Items.Add("amizade"); lstImagem.SelectedIndex = -1; // pega a lista de fontes disponíveis InstalledFontCollection fonts = new InstalledFontCollection(); foreach (FontFamily family in fonts.Families) { lstNomeDaFonte.Items.Add(family.Name); } // Defina o estilo da borda string[] borderStyleArray = Enum.GetNames(typeof(BorderStyle)); lstBorda.DataSource = borderStyleArray; lstBorda.DataBind(); // Selecina a primeira opção lstBorda.SelectedIndex = 0; } } protected void cmdAtualiza_Click(object sender, EventArgs e) { AtualizaCartao(); } protected void AtualizaCartao() { // Atualiza a cor pnlCartao.BackColor = Color.FromName(lstCorDeFundo.SelectedItem.Text); lblTexto.ForeColor = Color.FromName(lstCorDaFonte.SelectedItem.Text); // Atualiza fonte lblTexto.Font.Name = lstNomeDaFonte.SelectedItem.Text; try { if (Int32.Parse(txtTamanhoDaFonte.Text) > 0) { lblTexto.Font.Size = FontUnit.Point(Int32.Parse(txtTamanhoDaFonte.Text)); } } catch { lblmsg.Text = "Tamanho da fonte inválido !"; } try { if (Int32.Parse(txtTamanhoDaFonte.Text) > 0) { lblTexto.Font.Size = FontUnit.Point(Int32.Parse(txtTamanhoDaFonte.Text)); } } catch { lblmsg.Text = "Tamanho da fonte inválido !"; } // localiza o TypeConverter adequado para a enumeração BorderStyle TypeConverter cnvrt = TypeDescriptor.GetConverter(typeof(BorderStyle)); // Atualiza o estilo da borda usando o avlor do converter. pnlCartao.BorderStyle = (BorderStyle)cnvrt.ConvertFromString(lstBorda.SelectedItem.Text); atualizaImagem(); // Define o texto lblTexto.Text = txtTexto.Text; } protected void lstImagem_SelectedIndexChanged(object sender, EventArgs e) { //chama a rotina para atualizar a fonte atualizaImagem(); } protected void atualizaImagem() { //verifica se é para exibir a imagem if (chkImagem.Checked) { //obtem a imagem selecionada e exibe if (lstImagem.SelectedIndex != -1) { string nomeImagem = lstImagem.SelectedItem.Text + ".jpg"; imgDefault.ImageUrl = @"~/Imagens/" + nomeImagem; imgDefault.Visible = true; } } else { //não exibe a imagem imgDefault.Visible = false; } } protected void ControlChanged(Object sender, EventArgs e) { // Atualiza o texto do cartão AtualizaCartao(); } } } |
Executando o projeto veremos que a atualização do cartão agora é automática. Basta selecionar qualquer opção que a alteração será visualizada de imediato.
Com isso concluímos o nosso exemplo onde recordamos a utilização de alguns controles Web Forms, seus eventos e como tratá-los via código.
Obs: Você deve tomar cuidado com a utilização da propriedade AutoPostBack visto que dependendo do cenário isso pode causar problemas em sua aplicação.
Pegue o projeto completo aqui: GeradorDeCartoes.zip
Mat 8:19
E, aproximando-se um escriba, disse-lhe: Mestre, seguir-te- ei para onde quer que fores.Mat 8:20
Respondeu-lhe Jesus: As raposas têm covis, e as aves do céu têm ninhos; mas o Filho do homem não tem onde reclinar a cabeça.Mat 8:21
E outro de seus discípulos lhe disse: Senhor, permite-me ir primeiro sepultar meu pai.Mat 8:22
Jesus, porém, respondeu-lhe: Segue-me, e deixa os mortos sepultar os seus próprios mortos.Referências: