Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to localize an enum and use something similar to Html.SelectListFor<T>

Let's say that I got the following class and enum:

public class MyModel
{
    [DisplayName("Min egenskap")]
    public MyEnum TheProperty {get;set;}
}

public enum MyEnum
{
  [DisplayName("Inga från Sverige")]
  OneValue,

  [DisplayName("Ett annat värde")]
  AnotherValue
}

The above code doesn't work since DisplayNameAttribute cannot be used on enums. Are there another attribute that can be used?

What I want to do is to generate a nice html select tag using something like Html.SelectListFor(m => m.TheProperty). The list would use the DisplayNameAttribute or similar attribute during generation.

Wanted result:

<select name="TheProperty">
<option value="OneValue">Inga från Sverige</option>
<option value="AnotherValue" selected="selected">Ett annat värde</option>
</select>
like image 748
jgauffin Avatar asked Dec 15 '10 14:12

jgauffin


2 Answers

An example of how to do this is to use the [Description] attribute on your enum:

public enum DaysOfWeek
{
    [Description("Monday")]
    Monday = 1,

    [Description("Tuesday")]
    Tuesday = 2
}

Then create this EnumerationHelper class that will allow you to get the Description attribute of your enum:

public static class EnumerationHelper
{
    //Transforms an enumeration description into a string 
    public static string Description<TEnum>(this TEnum enumObject)
    {
        Type type = enumObject.GetType();
        MemberInfo[] memInfo = type.GetMember(enumObject.ToString());

        if(memInfo != null && memInfo.Length > 0)
        {
            DescriptionAttribute[] attributes = (DescriptionAttribute[])memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

            if (attributes.Length > 0)
            {
                return attributes[0].Description;
            }
        }

        return enumObject.ToString();

    }
}

Then you can query your enum class to get the value and description to then build a SelectList. You must reference the EnumerationHelper in this class:

var listOfDaysOfWeek = (from DaysOfWeek d in Enum.GetValues(typeof(DaysOfWeek))
                        select new { ID = d, Description = d.Description() });

viewModel.selectListDaysOfWeek = new SelectList(listOfDaysOfWeek, "ID", "Description");

And then finally in your view:

<%: Html.DropDownListFor(m => m.DayOfWeek, Model.DaysOfWeek) %>

I hope this helps.

like image 65
JayneT Avatar answered Nov 15 '22 06:11

JayneT


I wanted to display the Enum in the view so I made a similar Html helper:

    /// <summary>
    /// Returns the [Description] value of a Enum member.
    /// </summary>
    /// <typeparam name="TModel"></typeparam>
    /// <typeparam name="TResult"></typeparam>
    /// <param name="helper"></param>
    /// <param name="expression"></param>
    /// <returns></returns>
    public static MvcHtmlString DisplayEnumFor<TModel, TResult>(this HtmlHelper<TModel> helper, 
        Expression<Func<TModel, TResult>> expression) where TResult : struct {
        TResult value = expression.Compile().Invoke(helper.ViewData.Model);
        string propName = ExpressionHelper.GetExpressionText(expression);

        var description = typeof(TResult).GetMember(value.ToString())[0]
            .GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
        if (description != null) {
            return MvcHtmlString.Create((description as DescriptionAttribute).Description);
        }

        return MvcHtmlString.Create(value.ToString());
    }

Usage:

@Html.DisplayEnumFor(m => m.SomeEnumProperty)
like image 45
kamranicus Avatar answered Nov 15 '22 06:11

kamranicus