Web – Expert – Mão na Massa
Criando um controle personalizado para ASP.NET
Criação de WebControl para controle de CheckBox com 3 estados
Do que trata o artigo |
· Criação de Web Control; · Javascript; · Embedded Resource; · WebResources. · Referência de Assemblies no Web.Config. |
|
Criar um componente web de três estados semelhante ao checkbox, que irá indicar quando seu valor está selecionado, não selecionado ou nulo. |
|
Em todos os projetos que necessitem controlar estados de ativo, inativo ou não definido e exibir isso de uma forma amigável ao usuário. |
Resumo do DevMan
Aqui veremos a criação de um controle web personalizado, baseado no controle CheckBox do ASP.NET que terá por diferencial, gerenciar três estados distintos. Além do selecionado, não selecionado, que já são comuns, irá indicar quando o valor está nulo.
Na grande parte dos projetos que desenvolvemos, sempre nos deparamos com a necessidade de apresentar algum dado com o estado ligado/desligado, verdadeiro/falso ou o básico zero/um, mas e se o valor representado não estiver preenchido. Onde fica o nulo nesta história? Neste artigo veremos a implementação de um controle web, um checkbox, para manutenção deste terceiro estado.
Criando o ambiente
Para criarmos e testarmos o Three State CheckBox (nome dado ao projeto), usaremos dois projetos no Visual Studio, um Class Library e um ASP.NET Web Application, respectivamente DevmediaWebControl e TestCheckBoxControl. O Projeto DevmediaWebControl deve ser configurado conforme mostra a Figura 1, onde é necessário alterar o Assembly name e o Default namespace.
Figura 1. Configuração do projeto DevMediaWebControl
Nota do DevMan
A configuração das propriedades do projeto em relação ao nome do Assembly e Namespace permite fazermos a organização lógica das classes criadas em nossos projetos.
Por padrão, uma aplicação do tipo ClassLibrary não traz a referência do assembly System.Web. Essa referência é necessária para que possamos criar um novo WebControl. Vamos adicionar a referência deste assembly em nosso projeto. Para isso, no Solution Explorer, clique com o botão direito do mouse na pasta References e selecione a opção Add Reference e selecione o assembly necessário, como mostra a Figura 2. Além do System.Web precisaremos também associar as bibliotecas System.Drawing e System.Design.
Figura 2. Associação de Assembly
Para simular o comportamento visual do checkbox padrão Asp.Net serão utilizadas algumas imagens conforme apresentado na Tabela 1, organizadas conforme Figura 3.
Imagem |
Nome |
Descrição |
|
CI.gif |
Checked Image |
|
CID.gif |
Checked Image Disabled |
|
CIO.gif |
Checked Image Over |
|
UI.gif |
Undefined Image |
|
UIO.gif |
Undefined Image Over |
|
UNI.gif |
Unchecked Image |
|
UNID.gif |
Unchecked Image Disabled |
|
UNIO.gif |
Unchecked Image Over |
Tabela 1. Relação de Imagens
Figura 3. Organização das imagens
Nota: As imagens apresentadas neste artigo podem ser encontradas juntamente com o download do código deste componente.
Mão na massa
No nosso projeto estamos utilizando as imagens apresentadas na Figura 3. Como opção, você poderá associar outras imagens em tempo de desenvolvimento, sendo que por padrão o componente terá em sua biblioteca todas essas imagens associadas como recursos web (WebResources).
Para que as imagens sejam compiladas em conjunto com o nosso código elas precisam ser marcadas individualmente como Embedded Resources, para isso, selecione-as no Solution Explorer, abra suas propriedades através da tecla de atalho F4 ou clique com o botão da direita e escolha a opção Properties e, atribua à propriedade Build Action a opção Embedded Resource, como mostra a Figura 4.
Figura 4. Propriedade de compilação para as imagens
O primeiro passo da codificação será a criação da classe com as propriedades do CheckBox. Por uma questão de organização o código está separado em dois arquivos representando o nosso componente.
A primeira parte do código da classe parcial com a definição das propriedades, apresentada na Listagem 1, traz também a associação dos recursos que serão distribuídos com nossa DLL. Nesta primeira parte criaremos a referência dos recursos de imagens e o javascript necessário.
Listagem 1. CheckBox.property.cs – Associação de Namespaces e Recursos do Assembly
using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Web.UI;
using System.Web.UI.Design;
#region [ Resources ]
[assembly: WebResource("DevMedia.Web.UI.WebControls.CheckBox.CheckBox.js", "application/x-javascript")]
[assembly: WebResource("DevMedia.Web.UI.WebControls.CheckBox.Img.CI.gif", "image/gif")]
[assembly: WebResource("DevMedia.Web.UI.WebControls.CheckBox.Img.CID.gif", "image/gif")]
[assembly: WebResource("DevMedia.Web.UI.WebControls.CheckBox.Img.CIO.gif", "image/gif")]
[assembly: WebResource("DevMedia.Web.UI.WebControls.CheckBox.Img.UI.gif", "image/gif")]
[assembly: WebResource("DevMedia.Web.UI.WebControls.CheckBox.Img.UIO.gif", "image/gif")]
[assembly: WebResource("DevMedia.Web.UI.WebControls.CheckBox.Img.UNI.gif", "image/gif")]
[assembly: WebResource("DevMedia.Web.UI.WebControls.CheckBox.Img.UNID.gif", "image/gif")]
[assembly: WebResource("DevMedia.Web.UI.WebControls.CheckBox.Img.UNIO.gif", "image/gif")]
#endregion
É possível associar estes recursos no arquivo de configuração do assembly (AssemblyInfo.cs), na pasta de propriedades do projeto.
Nota: A associação dos recursos web no arquivo AssemblyInfo é uma opção interessante pois com isso centralizamos todos os recursos necessários para nossos componentes em um único local, em contrapartida, quando nossa biblioteca de classes atinge um número maior de componentes este arquivo de configuração pode ficar um pouco extenso e acabará tornando-se mais difícil de gerenciar. Um outro fator relevante é que se quisermos dividir nossas classes em mais de um assembly será necessário copiar estas informações para o novo projeto. No caso de mantermos a declaração de recursos juntamente com as classes, estas informações ficam logicamente melhor posicionadas.
A segunda parte do código com a definição das propriedades está apresentado na Listagem 2. O código está bem comentado, de forma que não repetirei aqui no texto as explicações. Em cada trecho de código, você pode encontrar um comentário sobre o que ele exatamente faz.
Listagem 2. CheckBox.property.cs – Definição de propriedades
namespace DevMedia.Web.UI.WebControls
{
/// <summary>
/// Checkbox Asp.Net (com imagens customizadas)
/// </summary>
public partial class CheckBox : System.Web.UI.WebControls.WebControl,
IPostBackDataHandler
{
private const string CHECKBOX_JS = "DevMedia.Web.UI.WebControls.CheckBox.CheckBox.js";
#region [ Campos ]
private bool _autoPostBack = false;
private bool _threeState = false;
private string _checkedImage;
private string _checkedImageOver = "";
private string _checkedImageDisabled;
private string _uncheckedImage;
private string _uncheckedImageDisabled;
private string _uncheckedImageOver = "";
private string _undefinedImage;
private string _undefinedImageOver;
private string _title = "";
private string _onClientClick = string.Empty;
#endregion
#region [ Propriedades ]
#region [ Comportamento (Postback / ThreeState / Client Click) ]
/// <summary>
/// Efetua o postback automático quando clicado.
/// </summary>
[Category("Behavior")]
[Description("Efetua o postback automático quando clicado.")]
[DefaultValue(false)]
public bool AutoPostBack
{
get { return _autoPostBack; }
set { _autoPostBack = value; }
}
/// <summary>
/// Indica se o checkbox aceita três estados ao invés de dois somente.
/// </summary>
[Category("Behavior")]
[Description("Indica se o checkbox aceita três estados ao invés de dois somente.")]
[DefaultValue(false)]
public bool ThreeState
{
get { return _threeState; }
set { _threeState = value; }
...