Quem sou eu

Minha foto
Programador por profissão, formação e opção! Interessado em tudo relacionado a computadores, menos manutenção de hardware! Linguagens (interesse e trabalho): Java, C#, C/C++, Python, Ruby, Haskell. Atualmente trabalhando como Desenvolvedor (maior parte do tempo em soluções ASP.NET)

terça-feira, 14 de julho de 2009

Asp.Net Child Controls

Criar controles customizados é uma parte importante do trabalho de desenvolvedores asp.Net. Muitas vezes os controles criados precisam manipular uma lista de controles filhos. (Child Controls).

Pensando nisso os desenvolvedores do Asp.Net criaram uma classe base para este tipo de controles, a CompositeControl.

A utilização da CompositeControl faz o trabalho de criar controles complexo uma tarefa bastate fácil, porém algumas vezes você precisa herdar de um controle que não é filho de CompositeControl, por exemplo customizar um Textbox.

Implementar as funcionalidades já presentes na ComposisteControle pode ser feita implementando alguns métodos.

  • CreateChildControls: Responsável por criar os controles filhos e adicioná-los à lista de controles filhos (this.Controls). O ideal é que a criação de controles filhos seja controlada dentro desta função, evitando que o código fique espalhado.
  • RenderChildren(HtmlTextWriter writer): Responsável por renderizar os controles filhos, o modo de operação padrão é simplesmente chamar o método RenderControl para cada um dos itens da lista (this.Controls).
  • Render(HtmlTextWriter writer): Este método apenas deve efetuar uma chamada ao método EnsureChildControls() e depois pode simplesmente chamar o método da classe base (base.Render(writer);)
  • EnsureChildControls: Este método não deve ser implementado, porém ele tem um papel fundamental. Seu objetivo é verificar a propriedade ChildControlsCreated e caso seja false, executar a chamada ao método CreateChildControls.
  • ChildControlsCreated: Sempre que for necessário recriar os itens filhos, o método ideal é setar essa propridade como false e posteriormente efetuar uma chamada ao método EnsureChildControls
O trecho de código abaixo cria um controle que apresenta um Label e um Textbox que são renderizados em conjunto, criando um campo que pode ser adicionado e ter um nome associado ao mesmo. Este tipo de controle é muito utilizado para fazer telas de preenchimento de formulários (cadastro de clientes, contatos, produtos, etc).



public class LabeledTextBox : WebControl
{
private Label _nameLabel;
private TextBox _field;

[Browsable(true)]
public Label NameLabel
{
get
{
EnsureChildControls();
return _nameLabel;
}
}

public TextBox Field
{
get
{
EnsureChildControls();
return _field;
}
}

protected override void CreateChildControls()
{
this.Controls.Clear();
base.CreateChildControls();
_nameLabel = new Label();
_nameLabel.ID = this.ID + "_Label";

_field = new TextBox();
_field.ID = this.ID + "_Textbox";

this.Controls.Add(_nameLabel);
this.Controls.Add(_field);
}

protected override void Render(HtmlTextWriter writer)
{
EnsureChildControls();
base.Render(writer);
}

protected override void RenderChildren(HtmlTextWriter writer)
{
_nameLabel.RenderControl(writer);
writer.WriteBreak();
_field.RenderControl(writer);
}
}


Esta classe é muito simples e não encapsula muito bem os controles, o ideal seria nunca exibir os controles filhos através de propridades públicas pois assim classes clientes podem se apoiar nas interfaces dos controles exibidos nas propriedades.
Sendo assim ao exibir os controles da maneira apresentada o controle fica preso e poderá somente utilizar controles de classes que descendem de Label e Textbox.