Criação de controles dinâmicos em .NET
Posted by Leticia Verta | Posted in .NET, C#, Geral | Posted on 18-12-2009-05-2008
2
Eis uma coisa que sempre encafifava minhas idéias: criação de controles dinâmicos no .NET.
Parece simples, porém, devido ao ‘complexo’ ciclo de vida das páginas da linguagem, se torna um pouco mais chatinho.
Vamos para o exemplo … que eu usei ainda hoje, diga-se de passagem
Criaremos uma página com um Panel e um Button
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>Relaxos - Controles Dinâmicos</title> </head> <body> <form id="form1" runat="server"> <div> <asp:Panel ID="pnlTeste" runat="server" /> <asp:Button ID="btnExibir" runat="server" Text="Botãozar" onclick="btnExibir_Click" /> </div> </form> </body> </html>
Agora criaremos, em tempo de execução, um TextBox e um Button – e seu respectivo evento. Exibiremos o conteúdo dos controles já adicionados através do btnExibir (notem que eu já setei um evento ao botão).
private TextBox txtDinamico; private Button btnDinamico; protected void Page_Load(object sender, EventArgs e) { CriarControles(); } private void CriarControles() { txtDinamico = new TextBox(); pnlTeste.Controls.Add(txtDinamico); btnDinamico = new Button(); btnDinamico.Text = "+"; btnDinamico.Click += new EventHandler(Adicionar); pnlTeste.Controls.Add(btnDinamico); } void Adicionar(object sender, EventArgs e) { CriarControles(); } protected void btnExibir_Click(object sender, EventArgs e) { StringBuilder stbConteudo = new StringBuilder(); //Pegamos todos os controles do pnlTeste foreach (Control oControl in pnlTeste.Controls) { //E filtramos para pegar os valores apenas dos TextBox's if (oControl.GetType().Name == "TextBox") stbConteudo.Append(String.Concat("\\nControle -> ", ((TextBox)oControl).UniqueID, " - ", ((TextBox)oControl).Text)); } Response.Write(String.Concat("alert('" , stbConteudo.ToString(), "');")); }
Rodando (ma oe) o projeto agora, vocês verão que os controles se perdem forever. A cada PostBack os controles somem, é como se nunca tivesse sido incluso nada ali. Isso acontece porque apenas as propriedades desses controles são serializadas, o controle em si não é, ou seja, teremos que persistir esses controles na raça … então let’s go:
public partial class ControlesDinamicos : System.Web.UI.Page { private TextBox txtDinamico; private Button btnDinamico; private int qtde { get { return Session["qtde"] == null ? 0 : Convert.ToInt32(Session["qtde"]); } set { Session["qtde"] = value; } } private int indice = 0; protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) //Cria o primeiro controle CriarControles(false); else { //Mantém controles posteriormente criados for (int c = 0; c < qtde; c++) CriarControles(true); } } private void CriarControles(bool Persistencia) { txtDinamico = new TextBox(); txtDinamico.ID = String.Concat("txtDinamico", indice); pnlTeste.Controls.Add(txtDinamico); btnDinamico = new Button(); btnDinamico.Text = "+"; btnDinamico.ID = String.Concat("btnDinamico", indice); btnDinamico.Click += new EventHandler(Adicionar); pnlTeste.Controls.Add(btnDinamico); indice++; if (!Persistencia) qtde++; } void Adicionar(object sender, EventArgs e) { CriarControles(false); } protected void btnExibir_Click(object sender, EventArgs e) { StringBuilder stbConteudo = new StringBuilder(); //Pegamos todos os controles do pnlTeste foreach (Control oControl in pnlTeste.Controls) { //E filtramos para pegar os valores apenas dos TextBox's if (oControl.GetType().Name == "TextBox") stbConteudo.Append(String.Concat("\\nControle -> ", ((TextBox)oControl).UniqueID, " - ", ((TextBox)oControl).Text)); } Response.Write(String.Concat("<script>alert('" , stbConteudo.ToString(), "');</script>")); } }
No código acima, quando acontece a persistência (que nada mais é a recriação de novos controles), os controles mudam os ids (Ex.: existem os controles ctl01, ctl02 … PostBack … na recriação serão ctl03, ctl04, por ai vai) e mais uma vez, cadê os dados?? Pra evitar essa bagunça, setamos a identidade de cada controle e VUALÁ!
Bom, agora é só colocar um ajaxzinho pra ficar biito e adequar às necessidades diárias … quem quiser o código, só clicar.
[]’s
Leticia Verta, desenvolvedora aspirante em .NET rs
