Martin at Mennt
Martin at Mennt

Reputation: 5737

Enum with multiple descriptions

I have my enum like this.

public enum Gender
{
    Man = 1,
    Woman = 2
}

And I use ASP MVC4 to display the choices in a drop down like this.

@Html.DropDownListFor(model => model.Gender, new SelectList(Enum.GetValues(typeof(Namespace.Models.Enum.Gender))))

This works like a charm, it display Man/Woman in the drop down. My problem is that I would like to show different names on those enums in different contexts.

Like one context would be if you are a Mom or a Dad. I would like to use the gender enum as base, but display Mom/Dad instad of Man/Woman.

Another context would be Boy/Girl, I still would like to use the gender enum, but display a different text.

Is this possible in any way?

EDIT I used Kevin's solution and also added another extention method like this.

public static List<KeyValuePair<string, int>> GetValues(IGenderStrategy genderStrategy)
    {
        Dictionary<string, int> arr = new Dictionary<string, int>();

        foreach (Gender g in System.Enum.GetValues(typeof(Gender)))
            arr.Add(g.ToValue(genderStrategy), (int)g);

        return arr.ToList();
    }

Which I used like this in my view.

@Html.DropDownListFor(model => model.Gender, new SelectList(Chores.Models.Enum.EnumExtentions.GetValues(new Chores.Models.Enum.ParentStrategy()), "value", "key"))

Upvotes: 0

Views: 1387

Answers (3)

Kevin Main
Kevin Main

Reputation: 2344

I like @RakotVT answer of using an extension method but would extend it a bit further as you would need a new extension method for every situation which is not great.

I think a variation of the Strategy pattern might work better here (http://www.dofactory.com/Patterns/PatternStrategy.aspx)

Something like this -

public enum Gender
{
    Man = 1,
    Woman = 2
}

public interface IGenderStrategy
{
    string DisplayName(Gender gender);
}

public class ParentStrategy : IGenderStrategy
{
    public string DisplayName(Gender gender)
    {
        string retVal = String.Empty;
        switch (gender)
        {
            case Gender.Man:
                retVal =  "Dad";
                break;
            case Gender.Woman:
                retVal =  "Mom";
                break;
            default:
                throw new Exception("Gender not found");
        }
        return retVal;
    }
}

public static class EnumExtentions
{
    public static string ToValue(this Gender e, IGenderStrategy genderStategy)
    {
        return genderStategy.DisplayName(e);
    }
}

public class Test
{
    public Test()
    {
        Gender.Man.ToValue(new ParentStrategy());
    }
}

Upvotes: 3

James S
James S

Reputation: 3588

Dunno if this is the neatest way, but how about something like:

@functions{
    IEnumerable<SelectListItem> GetGenderSelectList(GenderContext genderContext)
    {
       return Enum.GetValues(typeof(Namespace.Models.Enum.Gender)).ToList().ConvertAll(x => new SelectListItem(){Value= x.ToString(), Text= GetGenderDescription(x, genderContext)});
    }

    string GetGenderDescription(Gender gender, GenderContext genderContext)
    {
       switch (GenderContext)
       {
           case Children: return gender == Man? "Boy" : "Girl";
           case Parents: return gender == Man? "Dad" : "Mom";
           default: return gender.ToString();
       }
    }
}

@Html.DropDownListFor(model => model.Gender, GetGenderSelectList(model.GenderContext))

Here 'GenderContext' is another Enum.

obviously you don't need to have those functions in the page functions - Could just add the list of items to the ViewBag before even getting to the view.

Upvotes: 0

RakotVT
RakotVT

Reputation: 21

Try to add Extentions class for your Enum. Here is an example of this class.

 
public static class EnumExtentions
{
    public static string ToChildValue(this Gender e)
    {
        string retVal = string.Empty;

        switch (e)
        {
            case Gender.Man:
                retVal = "Boy";
                break;
            case Gender.Woman:
                retVal = "Girl";
                break;
        }
        return retVal;
    }


    public static string ToParentValue(this Gender e)
    {
        string retVal = string.Empty;

        switch (e)
        {
            case Gender.Man:
                retVal = "Dad";
                break;
            case Gender.Woman:
                retVal = "Mom";
                break;
        }
        return retVal;
    }
}

Upvotes: 1

Related Questions