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

2 comentarios sobre “databindig a una enumeracion (enum)”

  1. Hola Sergio, antes de nada comentarte que este no es el primer post que utilizo, asi que gracias por la ayuda prestada de antemano.

    Mi duda es la siguiente: he observado que en tu rutina de ConvertEnumForBinding asignas el member.name a una string y por otro lado obtenemos el valor de la descripción, y si quisiera coger el valor de cada miembro del enumarado? Es decir, en el caso de este post sería 1, 2 y 3 para posteriormente guardarlo en mi bdd.

  2. Holas Cristina!

    Esa es la idea de los post, que les puedan servir a otros que pasen por una situación parecida, y que bueno saber que hay gente que le sirve :).

    Ahora con respecto a tu pregunta, y dentro de tu capa de acceso a datos, si la usas, sino en el método de insertar a la base de datos:

    if (tuObjeto.ESTNoticia != null)
    {
    sqlDB.AddInParameter
    (cmd, “notEstado”, DbType.Int32,
    (int)tuObjeto.ESTNoticia);
    }

    Sobre el código anterior, decir que la enumeración es un atributo de un objeto, además que esta declarada como Nullable, por eso lo puedo comparar con null.

    (int), sirve para sacar el valor entero de una enumeración. Que lo puedes hacer hasta el final, es decir cuando vas hacer el ingreso a la base de datos. El código anterior en resumen agrega un parámetro al SP.

    Espero que te sirva :).

    Saludos,

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *