databindig a una enumeracion (enum)
Holas!
Ya en un post del anio pasado xD, habíamos comentado como usar una estructura enumeración en el modelo de n-capas, específicamente cuando tenemos que usar valores constantes como estados de noticia, aprobado, sinrevisar, novalida, y así.
Pues generalmente estos mismos valores, en sí los contenidos, ya que sólo los valores van a la base de datos, pero los contenidos son los que usamos y los que mostraremos. Como decía estos valores los necesitaremos en un ComboBox o un DropDownList, y es obvio que llenarlos manualmente se perdería productividad al hacer algún cambio futuro en los estados de una noticia por ejemplo. Lo óptimo es enlazarlo directamente a la enumeración de tal manera que no tengo que preocuparme al realizar un cambio.
Encontré, una encontré la otra la adapte, dos formas de hacerlo: una usando System.Reflection, y la otra no.
Método 01: Este me parece interesante porque te da la posibilidad de poner una descripción que después se puede usar para presentar al usuario:
private List<EnumerationValue> ConvertEnumForBinding(System.Enum enumeration)
{
List<EnumerationValue> results = new List<EnumerationValue>();
// Use reflection to see what values the enum provides
MemberInfo[] members = enumeration.GetType().GetMembers();
foreach (MemberInfo member in members)
{
// See if the member has a Description attribute:
object[] descriptionAttributes =
member.GetCustomAttributes(typeof(DescriptionAttribute), true);
if (descriptionAttributes.Length > 0)
{
string description =
((DescriptionAttribute)descriptionAttributes[0]).Description;
string value = member.Name;
results.Add(new EnumerationValue(description, value));
}
}
return results;
}
Imaginemos que la enumeración sea la siguiente:
public enum EstadoNoticia
{
[Description("Sin Revisar")]
SinRevisar = 1,
[Description("Publicada")]
Publicada = 2,
[Description("No Valida")]
NoValida = 3
}
Para enlazarlo a un dropdownlist sería de la siguiente forma:
ddlEstNoticia.DataSource = ConvertEnumForBinding(new EstadoNoticia());
ddlEstNoticia.DataTextField = "DisplayText"
ddlEstNoticia.DataValueField = "Value"
ddlEstNoticia.DataBind();
Por cierto, la definición de EnumerationValue es la siguiente:
public class EnumerationValue
{
private string _displayText;
private object _value;
public EnumerationValue()
{
}
public EnumerationValue(string displayText, object value)
{
_displayText = displayText;
_value = value;
}
public string DisplayText
{
get { return _displayText; }
}
public object Value
{
get { return _value; }
}
}
Se me pueden ocurrir recuperar dos cosas, una el valor entero o la enumeración misma:
En mi caso necesito la enumeración, que es la que pasaré a través de las capas:
EstadoNoticia val;
val = (EstadoNoticia)Enum.Parse(
typeof(EstadoNoticia), ddlEstNoticia.SelectedValue, true);
Y el Método 02:
private List<EnumerationValue> ConvertEnumForBinding2(System.Enum enumeration)
{
List<EnumerationValue> results = new List<EnumerationValue>();
Type todos = enumeration.GetType();
foreach (string s in Enum.GetNames(todos))
{
string value = Enum.Format(todos,Enum.Parse(todos, s), "d");
results.Add( new EnumerationValue(s,value));
}
return results;
}
En este caso el DisplayText será el valor de la enumeración por ejemplo "SinRevisar", y el Value será el valor numérico. Algo que rescatar en este segundo método es la forma de convertir un string a una enumeración. Además también se podría usar el método IsDefined para comprobar si el string existe como enumeración. Para ver todos los métodos de una enumeración ver aquí.
P.D.: En este ejemplo, por fines didácticos se muestra como si todo se hiciera en una sola capa, pero en un modelo en capas se encapsularía el método de traer los estados, por ejemplo:
ddlEstNoticia.DataSource = NOTAgente.ListarEstadosNoticia();
Saludos,
Post cruzado