Trying to work with @Html.CheckBox for to display text of enum

asp.net-mvc, asp.net-mvc-3, asp.net-mvc-4, c#, enums

Solution

I like using data annotations for this kind of thing. This prevents the craziness with trying to figure out a variable-to-readable text convention.

public enum MyEnum
{
    [Description("I like beer")]
    Beer = 1,
    [Description("I hate vodka")]
    Vodka = 2,
    [Description("Meh, rum")]
    Rum = 3
};

You can access the value at runtime using reflection:

MyEnum sampleEnum = MyEnum.Beer;
var attr = typeof(MyEnum)
    .GetMember(sampleEnum.ToString())
    .First()
    .GetCustomAttributes(typeof(DescriptionAttribute), false)
    .First() as DescriptionAttribute;
string description = attr.Description;

Of course, that's a bit verbose (and still needs error handling), but you can create an extension method to simplify the usage syntax:

public static string GetDescriptionOrDefault<T>(this T enumValue, string defaultValue = null)
{
    var attr = typeof(T)
        .GetMember(enumValue.ToString())
        .First()
        .GetCustomAttributes(typeof(DescriptionAttribute), false)
        .FirstOrDefault() as DescriptionAttribute;
    return attr == null ? (defaultValue ?? enumValue.ToString()) : attr.Description;
}

This would allow the view to write simply:

MyEnum sampleEnum = MyEnum.Beer;
string description = sampleEnum.GetDescriptionOrDefault();

Problem

I started doing this to display some checkboxes in my view: ``` @Html.LabelFor(m => m.MyEnum, T("Pick Your Poison")) <div> @for(int i = 0; i < Model.Alcohol.Count; i++) { <label> @T(Model.Alcohol[i].Text) @Html.CheckBoxFor(m => Model.Alcohol[i].Selected) @Html.HiddenFor(m => Model.Alcohol[i].Value) </label> } </div> ``` PLEASE NOTE: The important thing here is the `@T` method, which is used to handle translations of the text into other languages. This works. I've got a simple `enum`, and some methods in the back end that turn it into text in the view. So, an `enum` such as: ``` public enum MyEnum { Beer = 1, Vodka = 2, Rum = 3 } ``` will display list of checkboxes with those 3 choices. In my ViewModel I do this: ``` Alcohol= Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Select(x => { return new SelectListItem { Text = x.ToString().ToUpper(), Value = ((int)x).ToString() }; }).ToList(); } ``` However, I want to have more descriptive text to accompany the checkbox. I would rather the `enum` have this or some similar type of system (I will explain the underscore): ``` public enum MyEnum { I_like_Beer = 1, I_hate_Vodka = 2, Meh__Rum = 3 } ``` I was trying to create a method to strip out the underscore and replace it with a space, and in the case of the double underscore replace it with a comma, so when the checkboxes displayed they would look like: I like Beer I hate Vodka Meh, Rum But I don't know how to. Also, I am not sure this would be the best thing to do. I would love to preserve the `@T` function because then I can easily translate things in my app. Otherwise, doing anything else will sort of kill that for me. Any examples of what I might should be doing? Thanks.

Original source

Related problems