Lier un Enum à une DropDownList dans MVC 4? [dupliquer]

cette question a déjà une réponse ici:

  • comment créer une dropdownlist à partir d'un enum dans ASP.NET MVC? 36 réponses

j'ai trouvé partout que le moyen commun de lier les Énums aux chutes est par les méthodes d'aide, qui semble un peu exagéré pour une tâche si simple en apparence.

Quelle est la meilleure façon de lier les enum à DropDownLists en ASP.Net MVC 4?

21
demandé sur Roach Lord 2013-06-24 20:57:38

7 réponses

je pense qu'il s'agit de la seule voie (propre), ce qui est dommage, mais au moins il ya quelques options là-bas. Je recommande d'avoir un oeil à ce blog: http://paulthecyclist.com/2013/05/24/enum-dropdown/

Désolé, c'est trop long à copier ici, mais l'essentiel est qu'il a créé une nouvelle méthode HTML helper pour cela.

tout le code source est disponible sur GitHub .

18
répondu Bernhard Hofmann 2013-06-24 17:15:13

vous pouvez à ceci:

@Html.DropDownListFor(model => model.Type, Enum.GetNames(typeof(Rewards.Models.PropertyType)).Select(e => new SelectListItem { Text = e }))
23
répondu Mr. Pumpkin 2014-01-24 00:55:10

Enums sont soutenus par le cadre depuis MVC 5.1:

@Html.EnumDropDownListFor(m => m.Palette)

texte affiché peut être personnalisé:

public enum Palette
{
    [Display(Name = "Black & White")]
    BlackAndWhite,

    Colour
}

lien MSDN: http://www.asp.net/mvc/overview/releases/mvc51-release-notes#Enum

13
répondu Mihkel Müür 2014-08-18 16:55:05

dans mon contrôleur:

var feedTypeList = new Dictionary<short, string>();
foreach (var item in Enum.GetValues(typeof(FeedType)))
{
    feedTypeList.Add((short)item, Enum.GetName(typeof(FeedType), item));
}
ViewBag.FeedTypeList = new SelectList(feedTypeList, "Key", "Value", feed.FeedType);

de mon point De Vue:

@Html.DropDownList("FeedType", (SelectList)ViewBag.FeedTypeList)
10
répondu Roach Lord 2014-05-08 18:51:01

la solution de PaulTheCyclist est en place. Mais je n'utiliserais pas RESX (je devrais ajouter un nouveau .fichier resx pour chaque nouvel enum??)

Voici mon expression HtmlHelper:

public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TEnum>> expression, object attributes = null)
{
    //Get metadata from enum
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    var enumType = GetNonNullableModelType(metadata);
    var values = Enum.GetValues(enumType).Cast<TEnum>();

    //Convert enumeration items into SelectListItems
    var items =
        from value in values
        select new SelectListItem
        {
            Text = value.ToDescription(),
            Value = value.ToString(),
            Selected = value.Equals(metadata.Model)
        };

    //Check for nullable value types
    if (metadata.IsNullableValueType)
    {
        var emptyItem = new List<SelectListItem>
        {
            new SelectListItem {Text = string.Empty, Value = string.Empty}
        };
        items = emptyItem.Concat(items);
    }

    //Return the regular DropDownlist helper
    return htmlHelper.DropDownListFor(expression, items, attributes);
}

Voici comment je déclare mes énums:

[Flags]
public enum LoanApplicationType
{
    [Description("Undefined")]
    Undefined = 0,

    [Description("Personal Loan")]
    PersonalLoan = 1,

    [Description("Mortgage Loan")]
    MortgageLoan = 2,

    [Description("Vehicle Loan")]
    VehicleLoan = 4,

    [Description("Small Business")]
    SmallBusiness = 8,
}

et voici l'appel D'une vue de rasoir:

<div class="control-group span2">
    <div class="controls">
        @Html.EnumDropDownListFor(m => m.LoanType, new { @class = "span2" })
    </div>
</div>

@Model.LoanType est une propriété modèle du type de prêt

mise à JOUR: Désolé, j'ai oublié d'inclure le code pour la fonction d'assistance ToDescription()

/// <summary>
/// Returns Description Attribute information for an Enum value
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string ToDescription(this Enum value)
{
    if (value == null)
    {
        return string.Empty;
    }
    var attributes = (DescriptionAttribute[]) value.GetType().GetField(
        Convert.ToString(value)).GetCustomAttributes(typeof (DescriptionAttribute), false);
    return attributes.Length > 0 ? attributes[0].Description : Convert.ToString(value);
}
4
répondu amhed 2013-06-24 17:32:48

techniquement, vous n'avez pas besoin d'une méthode d'aide, puisque Html.DropdownListFor nécessite seulement un SelectList ou Ienumerable<SelectListItem> . Vous pouvez simplement transformer vos enums en une telle sortie et l'alimenter de cette façon.

j'utilise une méthode de bibliothèque statique pour convertir enums en List<SelectListItem> avec quelques paramètres / options:

public static List<SelectListItem> GetEnumsByType<T>(bool useFriendlyName = false, List<T> exclude = null,
    List<T> eachSelected = null, bool useIntValue = true) where T : struct, IConvertible
{
    var enumList = from enumItem in EnumUtil.GetEnumValuesFor<T>()
                    where (exclude == null || !exclude.Contains(enumItem))
                    select enumItem;

    var list = new List<SelectListItem>();

    foreach (var item in enumList)
    {
        var selItem = new SelectListItem();

        selItem.Text = (useFriendlyName) ? item.ToFriendlyString() : item.ToString();
        selItem.Value = (useIntValue) ? item.To<int>().ToString() : item.ToString();

        if (eachSelected != null && eachSelected.Contains(item))
            selItem.Selected = true;

        list.Add(selItem);
    }

    return list;
}

public static class EnumUtil
{
    public static IEnumerable<T> GetEnumValuesFor<T>()
    {
        return Enum.GetValues(typeof(T)).Cast<T>();
    }
    // other stuff in here too...
}


/// <summary>
/// Turns Camelcase or underscore separated phrases into properly spaces phrases
/// "DogWithMustard".ToFriendlyString() == "Dog With Mustard"
/// </summary>
public static string ToFriendlyString(this object o)
{
    var s = o.ToString();
    s = s.Replace("__", " / ").Replace("_", " ");

    char[] origArray = s.ToCharArray();
    List<char> newCharList = new List<char>();

    for (int i = 0; i < origArray.Count(); i++)
    {
        if (origArray[i].ToString() == origArray[i].ToString().ToUpper())
        {
            newCharList.Add(' ');
        }
        newCharList.Add(origArray[i]);
    }

    s = new string(newCharList.ToArray()).TrimStart();
    return s;
}

votre ViewModel peut passer dans les options que vous voulez. Voici une assez complexe:

public IEnumerable<SelectListItem> PaymentMethodChoices 
{ 
    get 
    { 
        var exclusions = new List<Membership.Payment.PaymentMethod> { Membership.Payment.PaymentMethod.Unknown, Membership.Payment.PaymentMethod.Reversal };
        var selected = new List<Membership.Payment.PaymentMethod> { this.SelectedPaymentMethod };
        return GetEnumsByType<Membership.Payment.PaymentMethod>(useFriendlyName: true, exclude: exclusions, eachSelected: selected); 
    }
}

votre vue DropDownList contre cette propriété IEnumerable<SelectListItem> .

4
répondu Graham 2013-06-24 17:51:42

étendre le helper html pour le faire fonctionne bien, mais si vous souhaitez être en mesure de changer le texte de la baisse des valeurs basées sur DisplayAttribute mappings, alors vous aurez besoin de le modifier similaire à cela,

(pré MVC 5.1, il est inclus dans l'5.1+)

public static IHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> html, Expression<Func<TModel, TEnum>> expression)
{
    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    var enumType = Nullable.GetUnderlyingType(metadata.ModelType) ?? metadata.ModelType;
    var enumValues = Enum.GetValues(enumType).Cast<object>();
    var items = enumValues.Select(item =>
    {
        var type = item.GetType();
        var member = type.GetMember(item.ToString());
        var attribute = member[0].GetCustomAttribute<DisplayAttribute>();
        string text = attribute != null ? ((DisplayAttribute)attribute).Name : item.ToString();
        string value = ((int)item).ToString();
        bool selected = item.Equals(metadata.Model);
        return new SelectListItem
        {
            Text = text,
            Value = value,
            Selected = selected
        };
    });
    return html.DropDownListFor(expression, items, string.Empty, null);
}
0
répondu Ryan Mann 2014-10-20 17:32:12