En muchos programas se suelen dar a los usuarios una serie de opciones para que escoja. Por ejemplo un tipo de búsqueda a realizar, un rango de posibles valores para parametrizar algún comportamiento, etc...
Lo más habitual es que estas opciones se "mapeen" después a elementos de una enumeración en el código de la capa de negocio. De esta forma si definimos una similar a esta:
public enum EstadoCivil
{
Casado,
Soltero,
Divorciado,
Viudo,
Religioso,
}
lo más común será que en la interfaz de usuario exista un modo de seleccionar algún valor equivalente, por ejemplo a través de una lista desplegable o un conjunto de botones de radio.
Es bastante habitual generar los elementos de la interfaz manualmente, añadiendo opciones a una lista Web o Windows, por ejemplo, con código similar a este:
lista.Items.Add(new ListItem("Casado", "0");
lista.Items.Add(new ListItem("Soltero", "1");
etc...
Sin embargo, sería muy útil poder añadir automáticamente los valores de una enumeración cualquiera sin preocuparse por saber cuántas son o cuál es su nombre. Gracias al poder de la reflexión en .NET esto es algo muy sencillo de conseguir.
Por ejemplo, la siguiente función toma como argumentos una referencia a un control de lista cualquiera de .NET (ListBox, CheckBoxList, DropDownList, etc...) y un valor enumerado cualquiera y rellena el control con tantas opciones como tenga disponibles dicha enumeración:
private void Enlaza(ListControl lst, Enum e)
{
string[] valores = Enum.GetNames(e.GetType());
foreach (string valor in valores)
lst.Items.Add(valor);
}
Toda la clave está en el método GetNames del tipo Enum, que devuelve una matriz con los nombres de cada elemento de la enumeración indicada. Así, para rellenar una lista sólo hay que escribir, por ejemplo:
Enlaza(miListBox, EstadoCivil.Casado);
o sea, se le pasa una referencia al control de lista y un miembro cualquiera de la enumeración.
Fácil ¿verdad?
La anterior función es muy sencilla pero puede dar algunos problemas. Por ejemplo, si al definir la enumeración se han declarado algunos miembros con valores específicos y diferentes a los valores por defecto, entonces el orden en la lista no coincidirá con el valor de cada miembro (0, 1, 2...). Se puede arreglar, pero complica algo la función. El código definitivo es el siguiente:
private void Enlaza(ListControl lst, Enum e)
{
Type tipo = Enum.GetUnderlyingType(e.GetType());
string[] nombres = Enum.GetNames(e.GetType());
Array valores = Enum.GetValues(e.GetType());
for(int i=0; i<nombres.Length;i++)
lst.Items.Add(new ListItem(nombres[i], Convert.ChangeType(valores.GetValue(i), tipo).ToString() ) );
}
Con esto ya queda totalmente definido. Se convierte cada uno de los valores a su tipo subyacente (para obtener su valor numérico, no su nombre) y luego se convierte en una cadena para añadirlo al ListItem. Lo bueno de este código es que, aunque un poco más complicado permite trabajar de forma genérica con cualquier enumeración, sin importar su tipo o la cantidad de elementos que tenga.
Se puede retocar la función para que, si se desea, se añada opcionalmente un elemento extra al principio o al final para permitir que el usuario escoja otra opción (por ejemplo, "Otro", "Ninguno", "[Cualquiera]"... dependiendo del contexto).