.NET

2 mai, 2008

Populando um ComboBox com Enumeradores

Publicidade

Olá a todos. Veremos nesse artigo como popular um ComboBox utilizando Enumeradores. Mas não será somente isso: utilizaremos atributos nos enumeradores para definir o valor de cada item do Enumerador que será mostrado no ComboBox.

Utilizei o Visual Studio 2008 para criar os projetos e, caso alguém não consiga abrir os mesmos, entre em contato que disponibilizo para o Visual Studio 2005. O arquivo para download está no final do artigo.

Crie um projeto Windows Application no Visual Studio.Net. No formulário que será criado, adicione um ComboBox e um Button. Esse ComboBox vai receber os valores do Enumerador, e o botão servirá para mostrarmos o item do Enumerador selecionado no ComboBox quando clicarmos nele. Servirá apenas para teste e validação de que tudo funcionou normalmente.

Crie o formulário como na imagem abaixo:

Feito isso, vá ao código fonte do formulário. Para isso pressione a tecla F7. Vamos criar agora o Enumerador que será populado no ComboBox.

Crie o Enumerador conforme mostrado no código abaixo:

Código em C#
/// <summary>
/// Enumerador com as opções de filtro da pesquisa de Clientes.
/// </summary>
enum Filtros
{ 
[Description("Código do Cliente")]
Codigo,
[Description("Nome do Cliente")]
Nome,
[Description("Endereço Residencial")]
Endereco
}
Código em VB.NET
''' <summary>
''' Enumerador com as opções de filtro da pesquisa de Clientes.
''' </summary>
Enum Filtros
      <Description("Código do Cliente")> _
      Codigo
      <Description("Nome do Cliente")> _
      Nome
      <Description("Endereço Residencial")> _
      Endereco
End Enum

Vamos agora ver um ponto interessante do código acima. Eu utilizei um DescriptionAtribute para adicionar uma descrição em cada item do Enumerador. E é exatamente o texto que estiver na descrição de cada item que será mostrado no ComboBox. Para utilizar Atributos, o namespace System.ComponentModel deve estar declarado em sua classe.

Para quem não conhece atributos ou quer se aprofundar no assunto, recomendo esse artigo de intrudução sobre o assunto http://www.microsoft.com/brasil/msdn/colunas/falandoc/col_falandoc_10.aspx

Muito bem, agora que já criamos o nosso Enumerador, vamos criar o método que vai obter a descrição de cada item do Enumerador.

Os códigos do método em questão estão abaixo:

Código em C#
/// <summary>
/// Obtém a descrição de um determinado Enumerador.
/// </summary>
/// <param name="valor">Enumerador que terá a descrição obtida.</param>
/// <returns>String com a descrição do Enumerador.</returns>
public static string ObterDescricao(Enum valor)
{
     FieldInfo fieldInfo = valor.GetType().GetField(valor.ToString());
     
     DescriptionAttribute[] atributos =   (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);

     return atributos.Length > 0 ? atributos[0].Description ?? "Nulo" : valor.ToString();
}
Código em VB.NET
''' <summary>
''' Obtém a descrição de um determinado Enumerador.
''' </summary>
''' <param name="valor">Enumerador que terá a descrição obtida.</param>
''' <returns>String com a descrição do Enumerador.</returns>
Public Shared Function ObterDescricao(ByVal valor As [Enum]) As String

     Dim fieldInfo As FieldInfo = valor.GetType.GetField(valor.ToString())
     Dim atributos As DescriptionAttribute() = _        DirectCast(fieldInfo.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
     
     Return IIf(atributos.Length > 0, IIf(atributos(0).Description Is    Nothing, "Nulo", atributos(0).Description), valor.ToString())

End Function

Analisando o método acima, nós passamos como parâmetro para o método um Enumerador. Utilizando Reflection, conseguimos obter o DescriptionAtribute do Enumerador passado. Caso o Enumerador possua um DescriptionAttribute, ele retorna a descrição do mesmo. Caso contrário, retorna o item do Enumerador. Para utilizar o FieldInfo, deverá ser adicionado o namespace System.Reflection na sua classe.

Para quem não conhece Reflection ou quer se aprofundar no assunto, segue um link introdutório sobre o mesmo http://www.linhadecodigo.com.br/Artigo.aspx?id=1518

Agora que criamos o método que obtém a descrição de um item de um Enumerador, vamos criar o método que retorna uma IList com os valores que serão populados no ComboBox.

Segue o código abaixo:

Código em C#
/// <summary>
/// Retorna uma lista com os valores de um determinado enumerador.
/// </summary>
/// <param name="tipo">Enumerador que terá os valores listados.</param>
/// <returns>Lista com os valores do Enumerador.</returns>
public static IList Listar(Type tipo)
{
     ArrayList lista = new ArrayList();
     if (tipo != null)
     {
          Array enumValores = Enum.GetValues(tipo);
          foreach (Enum valor in enumValores)
          {
               lista.Add(new KeyValuePair<Enum, string>(valor, ObterDescricao(valor)));
          }
     }
            
     return lista;
}
Código em VB.NET
''' <summary>
''' Retorna uma lista com os valores de um determinado enumerador.
''' </summary>
''' <param name="tipo">Enumerador que terá os valores listados.</param>
''' <returns>Lista com os valores do Enumerador.</returns>
Public Shared Function Listar(ByVal tipo As Type) As IList
     Dim lista As New ArrayList()
     If tipo IsNot Nothing Then
          Dim enumValores As Array = [Enum].GetValues(tipo)
          For Each valor As [Enum] In enumValores
               lista.Add(New KeyValuePair(Of [Enum], String)(valor, ObterDescricao(valor)))
          Next
     End If
     
     Return lista

End Function

Analisando o método acima, vemos que o método recebe um Type . Criamos um ArrayList que será populado com KeyValuePair contendo o Enumerador e a Descrição do mesmo.

Feito isso, no evento Load do nosso formulário, vamos chamar o método para popular o ComboBox.

Segue código abaixo:

Código em C#
private void Form1_Load(object sender, EventArgs e)
{
     comboBox1.DataSource = Listar(typeof(Filtros));
     comboBox1.DisplayMember = "Value";
     comboBox1.ValueMember = "Key";
}
Código em VB.NET
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
     ComboBox1.DataSource = Listar(GetType(Filtros))
     ComboBox1.DisplayMember = "Value"
     ComboBox1.ValueMember = "Key"
End Sub

Nesse código informamos que a propriedae DataSource do ComboBox recebe o retorno do método Listar que criamos anteriormente, como o método Listar recebe um Type como parâmetro enviamos o Type do nosso enumerador, typeof(Filtros) para C# e GetType(Filtros) para VB.NET.

Como a classe KeyValuePair trabalha com Chave e Valor, definimos na propriedade DisplayMember que ela irá mostrar o que estiver no Value da classe KeyValuePair (no caso a descrição do item do Enumerador) e a propriedade ValueMember vai receber o que estiver na propriedade Key (no caso o item do Enumerador).

Para finalizar e testar o nosso código, volte para o Design do formulário e de um duplo clique no Button para escrevermos o método que irá mostrar em um MessageBox o item do Enumerador selecionado no ComboBox.

Segue o código abaixo:

Código em C#
private void button1_Click(object sender, EventArgs e)
{
     Filtros filtro = (Filtros)comboBox1.SelectedValue;
     MessageBox.Show(filtro.ToString());
}
Código em VB.NET
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

     Dim filtro As Filtros = DirectCast(ComboBox1.SelectedValue, Filtros)
     MessageBox.Show(filtro.ToString())

End Sub

Analisando o código acima, pode ser observado que instanciamos um novo Enumerador do tipo do Enumerador que criamos e passamos para ele o valor que foi selecionado no ComboBox, para isso convertemos o objeto contino na propriedade SelectedValue do ComboBox para o tipo do nosso Enumerador. Depois mostramos uma mensagem com o Enumerador instanciado.

O resultado final deve ser igual o mostrado na imagem abaixo:

Como pode ser visto, mesmo selecionando o item “Endereço Residencial” do ComboBox, o valor que pegamos dele é o item Endereco do Enumerador.

Vimos nesse artigo uma forma simples de popular um ComboBox utilizando Enumeradores contendo em cada um dos seus itens um DescriptionAttribute. Isso é muito útil para mostrarmos informações aos usuários mantendo o uso de nossos Enumeradores.

Arquivo com os projetos em C# e VB.NET.

Abraços a todos e até o próximo artigo!