84 votes

MVC3 Razor DropDownListFor Enums

Essayer d'obtenir mon projet mis à jour à MVC3, quelque chose que je ne peux pas trouver:

J'ai un type de données simple d'ÉNUMÉRATIONS:

public enum States()
{
  AL,AK,AZ,...WY
}

Je veux l'utiliser comme une liste Déroulante/SelectList de mon point de vue d'un modèle qui contient ce type de données:

public class FormModel()
{
    public States State {get; set;}
}

Assez simple: quand je vais à utiliser la fonction d'auto-générer vue pour cette classe partielle, il ignore ce type.

J'ai besoin d'une simple liste de sélection qui définit la valeur de l'énumération que l'élément sélectionné lorsque j'ai frappé à traiter et soumettre par l'intermédiaire de mon AJAX, JSON Méthode POST.

Et que la vue (???!):

    <div class="editor-field">
        @Html.DropDownListFor(model => model.State, model => model.States)
    </div>

merci d'avance pour les conseils!!!

198voto

Mike McLaughlin Points 1841

J'ai trouvé une solution plus simple pour cela ici: http://coding-in.net/asp-net-mvc-3-method-extension/

 using System;
using System.Linq.Expressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace EnumHtmlHelper.Helper
{    
    public static class EnumDropDownList
    {
        public static HtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> modelExpression, string firstElement)
        {
            var typeOfProperty = modelExpression.ReturnType;
            if(!typeOfProperty.IsEnum)
                throw new ArgumentException(string.Format("Type {0} is not an enum", typeOfProperty));     
            var enumValues = new SelectList(Enum.GetValues(typeOfProperty));
            return htmlHelper.DropDownListFor(modelExpression, enumValues, firstElement);
}   }   }
 

Une ligne de rasoir le fera:

 @Html.DropDownListFor(model => model.State, new SelectList(Enum.GetValues(typeof(MyNamespace.Enums.States))))
 

Vous pouvez également trouver du code pour le faire avec une méthode d'extension dans l'article lié.

55voto

jgauffin Points 51913

Je viens de faire un pour mon propre projet. Le code ci-dessous est une partie de ma classe d'aide, j'espère que j'ai eu toutes les méthodes nécessaires. Écrire un commentaire si ça ne fonctionne pas, et je vais vérifier de nouveau.

public static class SelectExtensions
{

    public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression)
    {
        if (expression.Body.NodeType == ExpressionType.Call)
        {
            MethodCallExpression methodCallExpression = (MethodCallExpression)expression.Body;
            string name = GetInputName(methodCallExpression);
            return name.Substring(expression.Parameters[0].Name.Length + 1);

        }
        return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1);
    }

    private static string GetInputName(MethodCallExpression expression)
    {
        // p => p.Foo.Bar().Baz.ToString() => p.Foo OR throw...
        MethodCallExpression methodCallExpression = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetInputName(methodCallExpression);
        }
        return expression.Object.ToString();
    }

    public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
    {
        string inputName = GetInputName(expression);
        var value = htmlHelper.ViewData.Model == null
            ? default(TProperty)
            : expression.Compile()(htmlHelper.ViewData.Model);

        return htmlHelper.DropDownList(inputName, ToSelectList(typeof(TProperty), value.ToString()));
    }

    public static SelectList ToSelectList(Type enumType, string selectedItem)
    {
        List<SelectListItem> items = new List<SelectListItem>();
        foreach (var item in Enum.GetValues(enumType))
        {
            FieldInfo fi = enumType.GetField(item.ToString());
            var attribute = fi.GetCustomAttributes(typeof(DescriptionAttribute), true).FirstOrDefault();
            var title = attribute == null ? item.ToString() : ((DescriptionAttribute)attribute).Description;
            var listItem = new SelectListItem
                {
                    Value = ((int)item).ToString(),
                    Text = title,
                    Selected = selectedItem == ((int)item).ToString()
                };
            items.Add(listItem);
        }

        return new SelectList(items, "Value", "Text", selectedItem);
    }
}

Utiliser comme:

Html.EnumDropDownListFor(m => m.YourEnum);

Mise à jour

J'ai créé alternative Html Helpers. Tout ce que vous devez faire pour les utiliser est de changer votre baseviewpage en views\web.config.

Avec eux, vous pouvez simplement faire:

@Html2.DropDownFor(m => m.YourEnum);
@Html2.CheckboxesFor(m => m.YourEnum);
@Html2.RadioButtonsFor(m => m.YourEnum);

Plus d'infos ici: http://blog.gauffin.org/2011/10/first-draft-of-my-alternative-html-helpers/

24voto

Vincent Sels Points 321

A partir de ASP.NET MVC 5.1 (RC1) , EnumDropDownListFor est inclus par défaut en tant que méthode d'extension de HtmlHelper .

17voto

stewartml Points 670

Si vous voulez quelque chose de vraiment simple, il existe un autre moyen, en fonction de la manière dont vous stockez l'état dans la base de données.

Si vous aviez une entité comme celle-ci:

 public class Address
{
     //other address fields

     //this is what the state gets stored as in the db
     public byte StateCode { get; set; }

     //this maps our db field to an enum
     public States State
     {
         get
         {
             return (States)StateCode;
         }
         set
         {
             StateCode = (byte)value;
         }
     }
}
 

Générer le menu déroulant serait aussi simple que cela:

 @Html.DropDownListFor(x => x.StateCode,
    from State state in Enum.GetValues(typeof(States))
    select new SelectListItem() { Text = state.ToString(), Value = ((int)state).ToString() }
);
 

LINQ n'est-il pas beau?

12voto

JM1990 Points 78

J'ai été capable de faire cela dans une seule ligne.

 @Html.DropDownListFor(m=>m.YourModelProperty,new SelectList(Enum.GetValues(typeof(YourEnumType))))
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X