Desenvolvimento - C#
C#: Máscaras Dinâmicas para textBox com qualquer tipo numérico (CEP , CPF, CNPJ, MOEDA , DATA)
Este artigo foi criado para descrever passo-a-passo uma maneira dinâmica e eficaz de aplicar máscaras a conteúdos numéricos de qualquer tipo em um texBox, utilizando C#.
por Jorge Armando Andrade e CorrêaVisando facilitar a vida de quem trabalha com desenvolvimento criei este artigo descrevendo passo-a-passo e elucidando através de código fonte uma maneira dinâmica e eficaz de aplicar máscaras a conteúdos numéricos de qualquer tipo em um texBox, utilizando C# (C Sharp).
Máscara, neste caso em questão, é um recurso de interface utilizado para assemelhar determinada informação(neste exemplo, numérica), visível no sistema, a maneira como estamos acostumados a manipulá-la na vida real.
Por exemplo, ao ver o número "00000000" inicialmente não podemos atribuir nenhuma informação característica adicional a ele, fora o fato de se constituir de uma cadeia numérica. Aplicando uma máscara, através da interface visual do sistema teremos "00000-000",o que pode nos levar a deduzir que este número se trata de um CEP. Este recurso é muito importante na prevenção de erros por parte do usuário assegurando ao mesmo a não necessidade de digitação de determinados dígitos que possam gerar equívocos durante a inserção dos dados no sistema.
Visando dinamizar este processo de "mascarar" um dado numérico em tempo real criei uma função principal que é capaz de adicionar uma mascara de qualquer tipo (CEP, CPF, CNPJ), o que pode facilitar a vida de alguns desenvolvedores, que como eu, inicialmente encontraram poucas referências a respeito.
Mas por que não usar um MaskedTextBox? Eu considero o MakedTextBox um tipo de textBox meio "engessado", com algumas limitações, e para o meu caso em questão achei mais eficiente a criação deste código fonte para manipulação do textBox.
Seguem abaixo algumas características do resultado expresso pelo código que será descrito:
- a inserção dos números ocorre da direita para a esquerda. Sendo assim num campo do tipo moeda (0,00) a inserção de seguidos "2" transcorreria da seguinte maneira:
0,02 -> 0,22 -> 2,22 -> 22,22
- a tecla BackSpace também se sucede da direita para a esquerda (sem perda visual da mascara) da seguinte maneira:
2,22 -> 0,22 -> 0,02
Acompanhem agora o detalhamento do código em questão:
Como exemplo, aplicarei máscara a dois tipos de dados: O CEF ("12345-678"), e o CNPJ("12345678/1234-12"). Note que no caso do CNPJ apresentam-se dois caracteres especiais. Farei isso para mostrar que o código abaixo pode aplicar a mascara com quantos caracteres forem necessários, bastando para isso definir a quantidade na chamada da função.
Passo 1: Primeiramente definiremos algumas propriedades iniciais para o textBox:
textAlign = rigth (alinhamento do texto para direita)
text = 00000-000 (para CEP) ou text = 00000000/0000-00 (para CNPJ) – valores iniciais
Passo 2: Definiremos no evento
Click do textBox o posicionamento do cursor para o final do mesmo, evitando
assim que o usuário clique no meio da string para alterá-la:
private void txtCEP_Click(object sender, EventArgs e)
{
txtCEP.SelectionStart = txtCEP.Text.Length + 1;
}
Passo 3: Chamaremos a função responsável pela mascara no evento KeyPress do textBox:
//atribui valor da tecla digitada e da string do texbox para dentro do objeto mascara
//posteriormente compara se a string é a tecla é numero, anulando-a caso contrário (mascara.mascaraNumero())
//e finalmente aplica a mascara (mascara.mascaraCEP)
private void txtCEP_KeyPress(object sender, KeyPressEventArgs e)
{
classeMascaraJa mascara = atribuiMascara((char)e.KeyChar, txtCEP.Text);
if (!(e.Handled = mascara.mascaraNumero(9)))//este numero(9) é a quantidade de caracteres maximo do campo
txtCEP.Text = mascara.mascaraCEP();
txtCEP.SelectionStart = txtCEP.Text.Length + 1;
}
private void txtCNPJ_KeyPress(object sender, KeyPressEventArgs e)
{
classeMascaraJa mascara = atribuiMascara((char)e.KeyChar, txtCNPJ.Text);
if (!(e.Handled = mascara.mascaraNumero(16)))
txtCNPJ.Text = mascara.mascaraCNPJ();
txtCNPJ.SelectionStart = txtCNPJ.Text.Length + 1;
}
private classeMascara atribuiMascara(char caractere, string texto)
{ //preenche atributos mascara
classeMascaraJa objetoMascara = new classeMascaraJa();
objetoMascara.recebeTecla(caractere);
objetoMascara.recebePalavra(texto);
return objetoMascara;
}
No evento KeyPress inicialmente chama-se uma função atribuiMascara, que é responsável por chamar a classe mascara instanciada.
Passo4: Este passo é a codificação da classe mascara. O código fonte e alguns comentários seguem.
class classeMascaraJa
{
//ATRIBUTOS--------
private char tecla;
private string palavra;
private Int32 fator = 1;
//METODOS PRIVATE--
private void retiraCaractere(char carac)
{ //retirando caractere da string
string[] campos = palavra.Split(carac);
palavra = Convert.ToDouble(string.Concat(campos)).ToString();
}
private void acrescentaZeros(int normal, int backspace)
{ //acrescentado zeros a string
while ((palavra.Length < normal) || ((palavra.Length < backspace) && (tecla == (char)Keys.Back)))
{
palavra = "0" + palavra;
}
}
private void retornaFator()
{ //compara se backspace
if (tecla == (char)Keys.Back)
fator = 3;
}
public void limpaNumero(char simbolo, int min, int max)
{ //chama funcao para retirada de caracter e insercao de zeros
retiraCaractere(simbolo);
acrescentaZeros(min, max);
retornaFator();
}
//funcao recebe quantidade de parter do numero, inicio e quantidade de caracteres de cada parte dentro da string, caracter e efetua qualquer tipo de mascara.
private void mascaraQualquer(Int32 quantidade, string[,] limites)
{
string partes = "";
Int32 contador = 0;
while (contador < quantidade)
{
partes += palavra.Substring(Convert.ToInt32(limites[contador, 0]), Convert.ToInt32(limites[contador, 1])) + limites[contador, 2];
contador = contador + 1;
}
palavra = partes;
}
//METODODS PUBLICOS----
public void recebeTecla(char x)
{
tecla = x;
}
public void recebePalavra(string y)
{
palavra = y;
}
//metodo recebe caracter e retorna falso se numero
public bool mascaraNumero(Int32 maximo)
{
if ((!char.IsNumber(tecla) || (palavra.Length >= maximo && Convert.ToInt32(palavra.Substring(0, 1)) != 0)) && (tecla != (char)Keys.Back))
return true;
else
return false;
}
//aplica a mascara no formato 00000-000
public string mascaraCEP()
{
limpaNumero("-", 7, 9);
string[,] partes = { { "0", "5", "-" }, { "5", Convert.ToString(1 + fator), "" } };
mascaraQualquer(2, partes);
return palavra;
}
//aplica a mascara no formato 00000000/0000-00
public string mascaraCNPJ()
{
string[] camposAux;
palavra = string.Concat(camposAux = palavra.Split("/"));
limpaNumero("-", 13, 15);
string[,] partes = { { "0", "8", "/" }, { "8", "4", "-" }, { "12", Convert.ToString(1 * fator), "" } };
mascaraQualquer(3, partes);
return palavra;
}}
Passo 5: Não há passo 5! Este é todo codigo que será preciso para converter tanto CEP quanto CNPJ para suas devidas máscaras. Se analisarem verão que o codigo é simples e totalmente reutilizável.
A operação principal para conversao de um tipo numero se encontra dentro de dois métodos: um public e um private.
No caso do CNPJ por exemplo:
public string mascaraCNPJ()
{
string[] camposAux;
palavra = string.Concat(camposAux = palavra.Split("/"));
limpaNumero("-", 13, 15);
string[,] partes = { { "0", "8", "/" }, { "8", "4", "-" }, { "12", Convert.ToString(1 * fator), "" } };
mascaraQualquer(3, partes);
return palavra;
}}
Extraimos previamente o caractere “/”. Em seguinda efetuamos a limpeza do numero com relação ao caractere “–“ (Obs: no caso do CEP não é preciso uma estracao previa pois só há um tipo de caractere (“-“). Em datas, por exemplo, tambem somente seria necessário extrair o “/” usando o metodo limpaNumero()).
Os Números que seguem o caractere são “13” que corresponde ao valor mínimo de caracteres(somente numeros) menos 1, e “15” ao valor máximo de caracteres + 1. No caso de data, CEP, CNPJ, o numero máximo e mínimo são o mesmo, mas no caso de um tipo moeda o valor minimo é 3 e o maximo depende do limite de valor.
Feita a limpeza afetuaremos agora a aplicação da mascara: Primeiro é necessário entender que o numero será dividido em partes. No caso do CEP duas partes (parte1: 00000 e parte2: 000, ou seja, antes e depois do digito) e no CNPJ tres partes.
Na array(vetor bidimensional) “partes” serão inseriadas a posição do primeiro digito e a quantidade de digitos de cada parte da string(correspondendo a cada linha da matriz) seguido do caractere a ser inserido.
Ex.: CNPJ: 01234567/9999-00
Após extração dos digitos ficaria: 01234567999900
Diviriremos entao em partes:
Parte1: 01234567 ; minimo = posição 0 ; quantidade = 8; caracter = /
{“0”,”8”,”/”}
Parte2: 9999; minimo = posicao 8; quantidade = 4; caracter = “-“
{“8”,”4”,”-“}
Parte3: 00; minimo = 12;
quantidade = ?
aqui depende, se a pessoa tiver digitado um numero seria 1 para inserção de mais 1, ficando assim com dois, mas se o usuario tiver teclado o backspace teria de ser 3 para se diminuir 1 e ficar com a quantidade correta. Solucionando esta questão faço uso da variável “fator” multiplicada ao valor 1.
Quantidade = 1 * fator ; caracter = “”
{"12",Convert.ToString(1*fator),""}
Definidos os limites da string final, basta chamar o metodo “mascaraQualquer(3, partes);”, com a quantidade de partes(3) e a string particionada.
Acredito e prego o compartilhamento do conhecimento, por isso, espero ter ajudado alguem em outra parte do Brasil.