

| com exemplos em VB |
| Componente para deixar forms em Vb semelhantes às telas do winnamp |
| Componente para colocar sua aplicação VB no Systray |
| Componente para transformar sua aplicação VB em serviço |
| Ferramentas úteis para quem usa Olap Server |
| |

![]() |
||||||||
|
|
||||||||
Criando um
Custom Web Control com máscaras
O ASP.NET sem dúvidas é uma grande revolução no desenvolvimento Web. Mas o ASP.NET, porém, não mudou a arquitetura da Web. A Web continua trabalhando com HTML e JavaScript no client, exatamente como antes. O ASP.NET apenas permite que nós esqueçamos disso por um tempo.
Mas só por um tempo. A montagem de uma bela interface gráfica na Web, a criação de um verdadeiro sistema web, com boa interface com o usuário, tudo isso depende do bom uso dos recursos do client. Assim sendo não podemos depender apenas do javascript gerado pelos webControls existentes, precisamos ter flexibilidade para gerar códigos javascript adicionais.
Mas o código javascript é tipicamente repetitivo. Por exemplo, se precisamos programar uma entrada de CPF, por exemplo, o javascript é o mesmo para todas as aplicações em que precisarmos da entrada de CPF. E ai está o segredo do ASP.NET. Ao nos afastar do desenvolvimento JavaScript o ASP.NET também nos permite generaliza-lo, criando custom web controls, de forma que possamos estar reutilizando os webControls criados por nós em qualquer aplicação.
A esta altura, se você já andou lendo a respeito deste assunto, deve estar imaginando que vou falar sobre os arquivos .ASCX . Mas não, não é este o assunto deste artigo. Isso porque os .ASCX, apesar de serem chamados de WebControls, tem vários problemas. Vejamos alguns :
Por esses motivos os ASCX não são verdadeiros WebControls, eles existem na arquitetura do .NET para fornecer uma rápida substituição para a utilização de #Includes, tornando-os mais orientados a objeto, porém se desejamos realmente obter a reutilização devemos criar um verdadeiro WebControl, que no ambiente do Visual Studio é chamado de Custom Web Control.
Vamos compilar o custom web control dentro de um assembly separado, um arquivo .dll, de forma que poderemos reaproveita-lo em qualquer projeto web. Para fazer isso vamos criar um projeto do tipo Web Control Library. Ao criarmos esse projeto já é criada para nós a estrutura de um custom web control básico.

Nosso controle, porém, terá por objetivo gerar uma máscara de entrada para CPF e telefone. Portanto, herdará todas as características de uma TextBox e adicionaremos novos recursos. Então podemos apagar tudo que encontra-se dentro da classe no arquivo .VB e alterarmos a herança.
Veja como fica :
<ToolboxData("<{0}:MascaraEntrada runat=server></{0}:MascaraEntrada>")> _
Public Class MascaraEntrada
Inherits System.Web.UI.WebControls.TextBox
End Class
Observe que alterei também os atributos da classe para poder determinar
a tag que nosso custom control usará quando for adicionado na página
web.
Como nosso controle irá fornecer 2 tipos de máscaras diferentes, CPF e telefone, devemos criar uma propriedade para que o programador que for reutilizar nosso controle possa configura-lo facilmente. Já que são opções, CPF ou TELEFONE, podemos criar um Enum e definir a propriedade como sendo do tipo deste Enum. Veja como fica :
<ToolboxData("<{0}:MascaraEntrada runat=server></{0}:MascaraEntrada>")> _
Public Class MascaraEntrada
Inherits System.Web.UI.WebControls.TextBox
Public Enum tpMascara
CPF = 0
TELEFONE = 1
End Enum
Dim vMascara As tpMascara
Public Property Mascara() As tpMascara
Get
Return (vMascara)
End Get
Set(ByVal Value As tpMascara)
vMascara = Value
End Set
End Property
End Class
Para que nosso controle possa realizar a criação da máscara
de entrada precisaremos de código javascript. Eis o código abaixo
:
function mascaraTelefone(objeto){
if (objeto.value.indexOf("-") == -1 && objeto.value.length > 5){ objeto.value = ""; }
if (objeto.value.length == 3){
objeto.value +="-";
}
}
function mascara_cpf(cpf)
{
var mycpf = '';
mycpf = mycpf + cpf.value;
if (mycpf.length == 3) {
mycpf = mycpf + '.';
cpf.value = mycpf;
}
if (mycpf.length == 7) {
mycpf = mycpf + '.';
cpf.value = mycpf;
}
if (mycpf.length == 11) {
mycpf = mycpf + '-';
cpf.value = mycpf;
}
if (mycpf.length == 14) {
}
}
Existem 2 alternativas para gerarmos o código acima. Podemos fazer
com que o componente renderize esse código ou podemos inserir esse
código em um arquivo .JS a parte.
Inserindo em um arquivo JS a parte este arquivo precisará estar presente sempre que o controle for utilizado. Isso, porém, é semelhante ao que já acontece com outros controles, como os controles de validação. Tais controles exigem a presença do diretório ASPNET_CLIENT e seus subdiretórios para funcionarem corretamente.
Existem truques com relação a organização do diretório ASPNET_CLIENT . Não devemos deixar nenhum arquivo diretamente no ASPNET_CLIENT, pois se ocorrer um conflito de nomes de arquivo com algum outro componente teremos problemas. Além disso precisamos também garantir que múltiplas versões do nosso componente possam rodar no mesmo servidor web.
Para fazer isso podemos criar abaixo do diretório ASPNET_CLIENT um sub-diretório com o nome do nosso componente e sua versão, por exemplo, Mascara01. Desta forma, quando houver uma 2a versão teremos uma pasta Mascara02 e assim as diferentes versões do nosso componente poderão conviver em um mesmo servidor.
Vamos fazer então a ligação entre nosso componente e o código javascript. Ambas as funções javascript foram programadas para rodarem no evento keypress da textbox. Então precisaremos adicionar um atributo na textbox para fazer a chamada da função em javascript.
Para isso deveremos sobrescrever um método chamado AddAtributestoRender. Este método é disparado no momento exato da renderização em que estão sendo adicionados atributos no componente.
Apenas para lembrar alguns conceitos, o componente que estamos criando herdou características da textbox, que por sua vez já havia herdado características de um webcontrol. Neste processo de herança, os controles anteriores (textbox, webcontrol) possuem métodos que eles permitem que seja substituidos. Esses métodos nos permitem personalizar características dos controles, como neste exemplo, em que adicionaremos atributos aos controles.
Veja como fica :
Protected Overrides Sub AddAttributesToRender(ByVal writer As System.Web.UI.HtmlTextWriter)
If Mascara = tpMascara.CPF Then
writer.AddAttribute("onkeypress", "mascara_cpf(this)")
Else
writer.AddAttribute("onkeypress", "mascaraTelefone(this)")
End If
MyBase.AddAttributesToRender(writer)
End Sub
Assim sendo, no código acima verificamos o tipo de máscara selecionado
e manipulamos o parâmetro recebido. Se a máscara for de CPF,
adicionamos o atributo chamando a função de CPF, se a máscara
for de telefone, fazemos o mesmo para telefone. Depois ainda precisamos chamar
o mesmo método nas superclasses, para desta forma manter as funcionalidades
que o componente já possuia (textbox).
Feito isso devemos então fazer uma chamada para o arquivo .JS. Esta chamada é basicamente uma tag <SCRIPT></SCRIPT> apontando para o arquivo em questão. Mas essa tag é um bloco de script que precisaremos adicionar cuidadosamente na página.
Imagine que o nosso componente possa ser utilizado várias vezes na mesma página. Podemos ter vários campos telefone, por exemplo. Neste caso precisamos ter o cuidado de garantir que este script não seja duplicado, esse script deve ser adicionado uma única vez para todas as instâncias do componente que sejam utilizadas na página.
Para tanto devemos dar um ID para esse script e testar se o ID já foi adicionado. Faremos isso no método onPreRender, que também precisaremos sobrescrever. Veja como fica :
Private Const idScript As String = "ScriptMascara"
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
If Not Me.Page.IsClientScriptBlockRegistered(idScript) Then
Page.RegisterClientScriptBlock(idScript, "<script src=""/aspnet_client/mascara01/mascara.js""></script>")
End If
End Sub
Pronto. Temos nosso componente pronto. Podemos compilar essa DLL, fazer referência em outros projetos web e inseri-la na toolbox, de forma a podermos estar sempre utilizando esse componente em nossos projetos.

Veja como ficou a classe completa :
Imports System.ComponentModel
Imports System.Web.UI
<ToolboxData("<{0}:MascaraEntrada runat=server></{0}:MascaraEntrada>")> _
Public Class MascaraEntrada
Inherits System.Web.UI.WebControls.TextBox
Private Const idScript As String = "ScriptMascara"
Public Enum tpMascara
CPF = 0
TELEFONE = 1
End Enum
Dim vMascara As tpMascara
Public Property Mascara() As tpMascara
Get
Return (vMascara)
End Get
Set(ByVal Value As tpMascara)
vMascara = Value
End Set
End Property
Protected Overrides Sub AddAttributesToRender(ByVal writer As System.Web.UI.HtmlTextWriter)
If Mascara = tpMascara.CPF Then
writer.AddAttribute("onkeypress", "mascara_cpf(this)")
Else
writer.AddAttribute("onkeypress", "mascaraTelefone(this)")
End If
MyBase.AddAttributesToRender(writer)
End Sub
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
If Not Me.Page.IsClientScriptBlockRegistered(idScript) Then
Page.RegisterClientScriptBlock(idScript, "<script src=""/aspnet_client/mascara01/mascara.js""></script>")
End If
End Sub End Class Dennes Torres
MCA,MCSD,MCSE,MCDBA
© Búfalo Informática,
Treinamento e Consultoria -
Rua Álvaro Alvim, 37 Sala 920 • Cinelândia • Rio de Janeiro • RJ
Tel.: (21)2262-1368 • e-Mail: contato@bufaloinfo.com.br