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!