Um dos grupos de controles mais úteis na ToolBox do Visual Studio são os Validators.

Agora vamos pensar na seguinte tarefa, ao criar uma pesquisa na web, precisamos torna obrigatória uma pergunta, mas essa pergunta é de múltipla escolha CheckBoxList. Como resolvemos essa situação já nenhum controle de validação, valide sozinho esse controle?

Vamos resolver essa situação utilizando o CustomValidator.

Quando eu perguntei sobre validar sozinho, eu quis frisar que nenhum controle de validação faz a validação de um CheckBoxList sem que seja feita algum tipo de programação.

A solução

Crie um projeto de WebSite em C# com seu visual studio 2005. Na página default.aspx crie um objeto CheckBoxList conforme a Listagem 01.


<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatDirection="Horizontal">

    <asp:ListItem>1</asp:ListItem>

    <asp:ListItem>2</asp:ListItem>

    <asp:ListItem>3</asp:ListItem>

    <asp:ListItem>4</asp:ListItem>

    <asp:ListItem>5</asp:ListItem>

</asp:CheckBoxList>
Listagem 01 – RadioButtonList.

Para criação desse controle apenas araste uma instância do CheckBoxList para a página e crie 5 itens, com a propriedade Text e Value iguais e correspondente aos valores de 1 a 5. Na Listagem 02 logo abaixo, temos o código do controle CustomValidator.


<asp:CustomValidator ID="CustomValidator1" runat="server"

ErrorMessage="Campo Obrigatório" OnServerValidate="ValidaCheckBox">

</asp:CustomValidator>
Listagem 02 – CustomValidator.

A propriedade mais importante é a OnServerValidate. Essa propriedade deve conter o nome do método que você quer executar para validar o CheckBoxList quando o evento ServerValidate for disparado. Esse evento é disparado sempre após o Load da página dentro do ciclo de vida da mesma.

O temos que fazer agora é codificar esse método ValidaCheckBox para executar o que precisamos para saber o controle contém informações válidas ou não.


protected void ValidaCheckBox(object sender, ServerValidateEventArgs args)

{

    args.IsValid = true;

    if (CheckBoxList1.SelectedIndex == -1)

    {

        args.IsValid = false;

    }

}
Listagem 03 – Método ValidaCheckBox.

Vamos comentar esse método. O método tem 2 parâmetros. O Primeiro do tipo object que contém a informação do objeto que dispara o evento e o segundo do tipo ServerValidateEventArgs. Esse segundo objeto contém um propriedade “booleana” chamada IsValid, que nos utilizamos para informar se a validação ocorreu com sucesso ou não.

Começamos o método informando que a propriedade é True. Se o CheckBoxList1 retorna a propriedade SelectedIndex == -1, isso significa que nenhuma opção foi selecionada, pois esse propriedade retorna o índice (começando de zero) da primeira opção seleciona pelo usuário no CheckBoxList. Então se acontecer dessa propriedade retornar -1, nós invalidamos o controle atribuindo o valor False a propriedade IsValid.

Quando o framework .Net detecta essa “falha”, o mesmo procede com o tratamento normal igual ao demais controles validators, invalidando a página.

Controle checkBox com informações inválidas
Figura 01 – Controle checkBox com informações inválidas.
Controle checkBox com informações válidas
Figura 02 – Controle checkBox com informações válidas.

Aprendemos a validar um CheckBoxList. Mas se você quiser validar mais de um CheckBoxList nas mesma página? Você responde prontamente: basta criar um CustomValidator para cada instância de CheckBoxList e um método de validação.

Mas se os campos não existirem em tempo de design? Se o seu formulário for dinâmico e você precisar criar e validar campos em tempo de execução? E se os campos puderem ser do tipo CheckBoxList? Então precisamos criar uma rotina que valide todos os controles existentes na página.

A solução

Crie um projeto de WebSite em C# com seu visual studio 2005. Na página default.aspx arraste um GridView e código dentro da tag deve ficar igual a Listagem 01.

Código da tag da default.aspx
Listagem 01 – Código da tag da default.aspx.

Porém para simular essa situação precisamos criar um código que crie controles em tempo de execução. Para isso vamos escrever o código da página default.aspx.cs igual a Listagem 02 e criar um arquivo xml chamado enquete.xml na pasta App_Data com o conteúdo igual a Listagem 03. Vamos utilizar um modelo simples de enquete apenas para ilustrar a criação de controles em tempo de execução e a validação de forma dinâmica que foco desse artigo.

Default.aspx.cs
Default.aspx.cs
Default.aspx.cs
Default.aspx.cs
Listagem 02 – Default.aspx.cs.
Conteúdo do arquivo enquete.xml
Listagem 03 – Conteúdo do arquivo enquete.xml.

Método GridView1_RowDataBound

Nesse método ocorre a criação dos controles em tempo de execução através do método Eval da classe DataBinder recuperamos do DataSource os valores da Ordem e do Tipo do controle relacionado a pergunta da pesquisa. Logo após carregamos um DataSet com o conteúdo do arquivo enquetes.xml. O valor do tipo de controle é utilizado no laço switch para sabermos qual classe devemos instanciar.

Caso o tipo seja igual a CheckBoxList então instanciamos um objeto do tipo CheckBoxList, atribuímos os valores das propriedades DataTextField, DataValueField e DataSource e executamos o método Databind. Dessa forma temos um controle que foi criado em tempo de execução e carregados com os dados que precisamos. Como o controle já “existe” podemos inseri-lo na célula que está contida na linha que está sendo criada nesse momento no GridView1.

Veja que fazemos referência à célula de índice zero e.Row.Cells[0].Controls.Add() porque no nosso GridView só temos uma coluna. Na maioria dos casos existem mais colunas, então você pode obter o índice da coluna dinamicamente através de um laço foreach.

O procedimento citado acima é repetido para os demais controles, sendo alterado apenas as classes dos respectivos controles.

Método ValidaCampos

Esse método é responsável pela validação pois está associado ao evento OnServerValidate do CustomValidator. O método iniciar percorrendo todas as linhas do GridView1 através de um laço foreach. Dentro desse primeiro laço, criamos um segundo laço foreach para percorrer a coleção de controles existente na célula de índice 0 (zero) em cada linha.

Devemos apenas nos lembrar que a referência da célula 0 (zero) só é feita de forma direta, pois o nosso GridView só tem uma coluna.

Dentro do segundo laço, fazemos o teste se o tipo do controle atual é igual a um valor esperado por nós. Porém a comparação é feita através da propriedade FullName do método GetType() do controle, pois dessa forma temos certeza que a classe que iremos utilizar ao realizar o Cast CheckBoxList ck = (CheckBoxList)ctrl; do tipo do controle, será a classe correta. Após a ter ocorrido o cast, temos um objeto com o tipo correto. Então basta fazer a verificação se a propriedade SelectIndex é igual a -1 e como no artigo anterior atribuir o valor para a variável args.

Campos requeridos
Figura 01 – Campos requeridos.