Um aluno fez a seguinte pergunta:
Eu tenho uma enumeração e quero criar um combo, na minha aplicação Silverlight, com os itens desse enum. Como faço isso usando C#?
Bom, associar itens do enum à propriedade DataSource do ComboBox é extremamente simples para aplicações Windows Forms. Basta usar o método GetValues() do System.Enum, e obter uma coleção com os elementos do enum - que será associada à propriedade DataSource:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WinFormsExemploEnumComboBox
{
enum Itens
{
um,
dois,
três,
quatro,
cinco
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
ComboBox cb = new ComboBox();
//36 = 10 da margem + 8 da borda (de cada lado)
cb.Width = this.Width - 36;
cb.Location = new Point(10, 10);
cb.DataSource = Enum.GetValues(typeof(Itens));
this.Controls.Add(cb);
}
}
}
Já, para web, usando ASP.NET, temos:
using System;
using System.Web.UI.WebControls;
enum Itens
{
um,
dois,
três,
quatro,
cinco
}
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DropDownList ddl = new DropDownList();
ddl.Width = 200;
ddl.DataSource = Enum.GetValues(typeof(Itens));
ddl.DataBind();
this.form1.Controls.Add(ddl);
}
}
Agora, para WPF, precisamos de um código diferente, já que o ComboBox não tem a propriedade DataSource:
using System;
using System.Windows;
using System.Windows.Controls;
namespace WPFExemploEnumComboBox
{
enum Itens
{
um,
dois,
três,
quatro,
cinco
}
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ComboBox cb = new ComboBox();
cb.HorizontalAlignment = HorizontalAlignment.Center;
cb.VerticalAlignment = VerticalAlignment.Center;
cb.Width = 200;
foreach (var item in Enum.GetValues(typeof(Itens)))
{
cb.Items.Add(item);
}
this.Content = cb;
}
}
}
Mas... como o ComboBox tem uma propriedade num projeto Windows Forms e não tem num WPF? Perdeu? Não!!! Somente o nome das classes é o mesmo. No Windows Forms temos o System.Windows.Forms.ComboBox e no WPF o System.Windows.Controls.ComboBox. Apesar do nome, temos duas classes bastante diferentes.
Finalmente, para o Silverlight, temos que usar Reflection, já que o seu Enum não possui o método GetValues():
using System.Windows;
using System.Windows.Controls;
using System.Reflection;
namespace SilverlightExemploEnumComboBox
{
enum Itens
{
um,
dois,
três,
quatro,
cinco
}
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
ComboBox cb = new ComboBox();
cb.HorizontalAlignment = HorizontalAlignment.Center;
cb.VerticalAlignment = VerticalAlignment.Center;
cb.Width = 200;
foreach (var item in typeof(Itens).GetFields(BindingFlags.Public
| BindingFlags.Static))
{
cb.Items.Add(item.GetValue(null));
}
this.Content = cb;
}
}
}
Como curiosidade, descompilei o GetValues() da classe System.Enum usando o .Net Reflector criado pelo Lutz Roeder. Segui o código até achar uma chamada ao InternalGetEnumValues(Type, ref ulong[], ref string[]), que é um método extern. Aí eu parei a "brincadeira":
[ComVisible(true)]
public static Array GetValues(Type enumType)
{
if (enumType == null)
{
throw new ArgumentNullException("enumType");
}
if (!(enumType is RuntimeType))
{
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),
"enumType");
}
if (!enumType.IsEnum)
{
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"),
"enumType");
}
ulong[] values = GetHashEntry(enumType).values;
Array array = Array.CreateInstance(enumType, values.Length);
for (int i = 0; i < values.Length; i++)
{
object obj2 = ToObject(enumType, values[i]);
array.SetValue(obj2, i);
}
return array;
}
