with tutorial net mvc enumdropdownlistfor enum dropdownlist asp asp.net asp.net-mvc

tutorial - ¿Cómo se crea una lista desplegable desde una enumeración en ASP.NET MVC?



mvc dropdownlist enum selected value (30)

Para MVC v5.1 use Html.EnumDropDownListFor

@Html.EnumDropDownListFor( x => x.YourEnumField, "Select My Type", new { @class = "form-control" })

Para MVC v5 use EnumHelper

@Html.DropDownList("MyType", EnumHelper.GetSelectList(typeof(MyType)) , "Select My Type", new { @class = "form-control" })

Para MVC 5 e inferior

Rodé la respuesta de Rune en un método de extensión:

namespace MyApp.Common { public static class MyExtensions{ public static SelectList ToSelectList<TEnum>(this TEnum enumObj) where TEnum : struct, IComparable, IFormattable, IConvertible { var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { Id = e, Name = e.ToString() }; return new SelectList(values, "Id", "Name", enumObj); } } }

Esto te permite escribir:

ViewData["taskStatus"] = task.Status.ToSelectList();

using MyApp.Common

Estoy tratando de usar el método de extensión Html.DropDownList pero no puedo entender cómo usarlo con una enumeración.

Digamos que tengo una enumeración como esta:

public enum ItemTypes { Movie = 1, Game = 2, Book = 3 }

¿Cómo hago para crear un menú desplegable con estos valores utilizando el método de extensión Html.DropDownList ?

¿O es mi mejor apuesta simplemente crear un bucle for y crear los elementos HTML manualmente?



Ampliando las respuestas de Premio y Runa, si desea que el atributo de valor de los elementos de su lista de selección se asigne al valor entero del tipo de enumeración, en lugar del valor de cadena, use el siguiente código:

public static SelectList ToSelectList<T, TU>(T enumObj) where T : struct where TU : struct { if(!typeof(T).IsEnum) throw new ArgumentException("Enum is required.", "enumObj"); var values = from T e in Enum.GetValues(typeof(T)) select new { Value = (TU)Convert.ChangeType(e, typeof(TU)), Text = e.ToString() }; return new SelectList(values, "Value", "Text", enumObj); }

En lugar de tratar cada valor de Enumeración como un objeto TEnum, podemos tratarlo como un objeto y luego convertirlo en entero para obtener el valor sin caja.

Nota: También agregué una restricción de tipo genérico para restringir los tipos para los que esta extensión está disponible solo para estructuras (tipo base de Enum), y una validación de tipo en tiempo de ejecución que garantiza que la estructura que se pasa sea de hecho un Enum.

Actualización 10/23/12: Se agregó un parámetro de tipo genérico para el tipo subyacente y se corrigió el problema de no compilación que afecta a .NET 4+.


Aquí hay una mejor solución encapsulada:

https://www.spicelogic.com/Blog/enum-dropdownlistfor-asp-net-mvc-5

Di aquí tu modelo:

Uso de la muestra:

UI generada:

Y generado HTML

La instantánea del código fuente de la extensión de ayuda:

Puede descargar el proyecto de muestra desde el enlace que proporcioné.

EDITAR: Aquí está el código:

public static class EnumEditorHtmlHelper { /// <summary> /// Creates the DropDown List (HTML Select Element) from LINQ /// Expression where the expression returns an Enum type. /// </summary> /// <typeparam name="TModel">The type of the model.</typeparam> /// <typeparam name="TProperty">The type of the property.</typeparam> /// <param name="htmlHelper">The HTML helper.</param> /// <param name="expression">The expression.</param> /// <returns></returns> public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class { TProperty value = htmlHelper.ViewData.Model == null ? default(TProperty) : expression.Compile()(htmlHelper.ViewData.Model); string selected = value == null ? String.Empty : value.ToString(); return htmlHelper.DropDownListFor(expression, createSelectList(expression.ReturnType, selected)); } /// <summary> /// Creates the select list. /// </summary> /// <param name="enumType">Type of the enum.</param> /// <param name="selectedItem">The selected item.</param> /// <returns></returns> private static IEnumerable<SelectListItem> createSelectList(Type enumType, string selectedItem) { return (from object item in Enum.GetValues(enumType) let fi = enumType.GetField(item.ToString()) let attribute = fi.GetCustomAttributes(typeof (DescriptionAttribute), true).FirstOrDefault() let title = attribute == null ? item.ToString() : ((DescriptionAttribute) attribute).Description select new SelectListItem { Value = item.ToString(), Text = title, Selected = selectedItem == item.ToString() }).ToList(); } }


Así que sin las funciones de Extensión, si estás buscando algo simple y fácil ... Esto es lo que hice

<%= Html.DropDownListFor(x => x.CurrentAddress.State, new SelectList(Enum.GetValues(typeof(XXXXX.Sites.YYYY.Models.State))))%>

donde XXXXX.Sites.YYYY.Models.State es una enumeración

Probablemente sea mejor hacer la función de ayudante, pero cuando el tiempo sea corto, esto hará el trabajo.


Bueno, realmente llego tarde a la fiesta, pero para lo que vale la pena, he escrito en este blog sobre este tema mediante el cual creo una clase EnumHelper que permite una transformación muy fácil.

http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23

En su controlador:

//If you don''t have an enum value use the type ViewBag.DropDownList = EnumHelper.SelectListFor<MyEnum>(); //If you do have an enum value use the value (the value will be marked as selected) ViewBag.DropDownList = EnumHelper.SelectListFor(MyEnum.MyEnumValue);

En su vista:

@Html.DropDownList("DropDownList") @* OR *@ @Html.DropDownListFor(m => m.Property, ViewBag.DropDownList as SelectList, null)

La clase de ayuda:

public static class EnumHelper { // Get the value of the description attribute if the // enum has one, otherwise use the value. public static string GetDescription<TEnum>(this TEnum value) { var fi = value.GetType().GetField(value.ToString()); if (fi != null) { var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes.Length > 0) { return attributes[0].Description; } } return value.ToString(); } /// <summary> /// Build a select list for an enum /// </summary> public static SelectList SelectListFor<T>() where T : struct { Type t = typeof(T); return !t.IsEnum ? null : new SelectList(BuildSelectListItems(t), "Value", "Text"); } /// <summary> /// Build a select list for an enum with a particular value selected /// </summary> public static SelectList SelectListFor<T>(T selected) where T : struct { Type t = typeof(T); return !t.IsEnum ? null : new SelectList(BuildSelectListItems(t), "Text", "Value", selected.ToString()); } private static IEnumerable<SelectListItem> BuildSelectListItems(Type t) { return Enum.GetValues(t) .Cast<Enum>() .Select(e => new SelectListItem { Value = e.ToString(), Text = e.GetDescription() }); } }


En ASP.NET MVC 5.1 , agregaron el ayudante EnumDropDownListFor() , por lo que no se necesitan extensiones personalizadas:

Modelo :

public enum MyEnum { [Display(Name = "First Value - desc..")] FirstValue, [Display(Name = "Second Value - desc...")] SecondValue }

Ver :

@Html.EnumDropDownListFor(model => model.MyEnum)

Usando Tag Helper (ASP.NET MVC 6) :

<select asp-for="@Model.SelectedValue" asp-items="Html.GetEnumSelectList<MyEnum>()">


Esta es la versión para Razor:

@{ var itemTypesList = new List<SelectListItem>(); itemTypesList.AddRange(Enum.GetValues(typeof(ItemTypes)).Cast<ItemTypes>().Select( (item, index) => new SelectListItem { Text = item.ToString(), Value = (index).ToString(), Selected = Model.ItemTypeId == index }).ToList()); } @Html.DropDownList("ItemTypeId", itemTypesList)


Estas son las respuestas de Rune & Prize modificadas para usar el valor Enum int como ID.

Enum de muestra:

public enum ItemTypes { Movie = 1, Game = 2, Book = 3 }

Método de extensión:

public static SelectList ToSelectList<TEnum>(this TEnum enumObj) { var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { Id = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() }; return new SelectList(values, "Id", "Name", (int)Enum.Parse(typeof(TEnum), enumObj.ToString())); }

Muestra de uso:

<%= Html.DropDownList("MyEnumList", ItemTypes.Game.ToSelectList()) %>

Recuerde importar el espacio de nombres que contiene el método de extensión

<%@ Import Namespace="MyNamespace.LocationOfExtensionMethod" %>

Muestra de HTML generado:

<select id="MyEnumList" name="MyEnumList"> <option value="1">Movie</option> <option selected="selected" value="2">Game</option> <option value="3">Book </option> </select>

Tenga en cuenta que el elemento que utiliza para llamar a ToSelectList es el elemento seleccionado.


Html.DropDownListFor solo requiere un IEnumerable, por lo que una alternativa a la solución de Prise es la siguiente. Esto te permitirá escribir simplemente:

@Html.DropDownListFor(m => m.SelectedItemType, Model.SelectedItemType.ToSelectList())

[Donde SelectedItemType es un campo en su modelo de tipo ItemTypes, y su modelo no es nulo]

Además, no es necesario que genere el método de extensión, ya que puede usar enumValue.GetType () en lugar de typeof (T).

EDITAR: La solución de Simon integrada también aquí, e incluye el método de extensión ToDescription.

public static class EnumExtensions { public static IEnumerable<SelectListItem> ToSelectList(this Enum enumValue) { return from Enum e in Enum.GetValues(enumValue.GetType()) select new SelectListItem { Selected = e.Equals(enumValue), Text = e.ToDescription(), Value = e.ToString() }; } public static string ToDescription(this Enum value) { var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false); return attributes.Length > 0 ? attributes[0].Description : value.ToString(); } }


La mejor solución que encontré para esto fue combinar este blog con la respuesta de Simon Goldstone .

Esto permite el uso de la enumeración en el modelo. Esencialmente, la idea es usar una propiedad entera, así como la enumeración, y emular la propiedad entera.

Luego use el atributo [System.ComponentModel.Description] para anotar el modelo con su texto de visualización, y use una extensión "EnumDropDownListFor" en su vista.

Esto hace que tanto la vista como el modelo sean muy legibles y mantenibles.

Modelo:

public enum YesPartialNoEnum { [Description("Yes")] Yes, [Description("Still undecided")] Partial, [Description("No")] No } //........ [Display(Name = "The label for my dropdown list")] public virtual Nullable<YesPartialNoEnum> CuriousQuestion{ get; set; } public virtual Nullable<int> CuriousQuestionId { get { return (Nullable<int>)CuriousQuestion; } set { CuriousQuestion = (Nullable<YesPartialNoEnum>)value; } }

Ver:

@using MyProject.Extensions { //... @Html.EnumDropDownListFor(model => model.CuriousQuestion) //... }

Extensión (directamente de la respuesta de Simon Goldstone , incluida aquí para completar):

using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.ComponentModel; using System.Reflection; using System.Linq.Expressions; using System.Web.Mvc.Html; namespace MyProject.Extensions { //Extension methods must be defined in a static class public static class MvcExtensions { private static Type GetNonNullableModelType(ModelMetadata modelMetadata) { Type realModelType = modelMetadata.ModelType; Type underlyingType = Nullable.GetUnderlyingType(realModelType); if (underlyingType != null) { realModelType = underlyingType; } return realModelType; } private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } }; public static string GetEnumDescription<TEnum>(TEnum value) { FieldInfo fi = value.GetType().GetField(value.ToString()); DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); if ((attributes != null) && (attributes.Length > 0)) return attributes[0].Description; else return value.ToString(); } public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression) { return EnumDropDownListFor(htmlHelper, expression, null); } public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes) { ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); Type enumType = GetNonNullableModelType(metadata); IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>(); IEnumerable<SelectListItem> items = from value in values select new SelectListItem { Text = GetEnumDescription(value), Value = value.ToString(), Selected = value.Equals(metadata.Model) }; // If the enum is nullable, add an ''empty'' item to the collection if (metadata.IsNullableValueType) items = SingleEmptyItem.Concat(items); return htmlHelper.DropDownListFor(expression, items, htmlAttributes); } } }


Llego muy tarde pero encontré una manera genial de hacer esto con una línea de código, si está feliz de agregar el paquete de Melody NuGet sin restricciones (una biblioteca agradable y pequeña de Jon Skeet).

Esta solución es mejor porque:

  1. Asegura (con restricciones de tipo genérico) que el valor es realmente un valor de enumeración (debido a una melodía sin restricciones)
  2. Evita el boxeo innecesario (debido a la melodía sin restricciones)
  3. Almacena en caché todas las descripciones para evitar el uso de la reflexión en cada llamada (debido a la melodía sin restricciones)
  4. ¡Es menos código que las otras soluciones!

Entonces, aquí están los pasos para que esto funcione:

  1. En la consola del Administrador de paquetes, "Install-Package UnconstrainedMelody"
  2. Agregue una propiedad en su modelo así:

    //Replace "YourEnum" with the type of your enum public IEnumerable<SelectListItem> AllItems { get { return Enums.GetValues<YourEnum>().Select(enumValue => new SelectListItem { Value = enumValue.ToString(), Text = enumValue.GetDescription() }); } }

Ahora que tiene la Lista de SelectListItem expuesta en su modelo, puede usar @ Html.DropDownList o @ Html.DropDownListFor usar esta propiedad como fuente.


Me encontré con el mismo problema, encontré esta pregunta y pensé que la solución provista por Ash no era lo que estaba buscando; Tener que crear el HTML por mí mismo significa menos flexibilidad en comparación con la función Html.DropDownList() incorporada.

Resulta que C # 3, etc., hace esto bastante fácil. Tengo una enum llamada TaskStatus :

var statuses = from TaskStatus s in Enum.GetValues(typeof(TaskStatus)) select new { ID = s, Name = s.ToString() }; ViewData["taskStatus"] = new SelectList(statuses, "ID", "Name", task.Status);

Esto crea una buena lista de SelectList que se puede usar como está acostumbrado en la vista:

<td><b>Status:</b></td><td><%=Html.DropDownList("taskStatus")%></td></tr>

El tipo anónimo y LINQ lo hacen mucho más elegante en mi humilde opinión. Sin ofender, Ash. :)


Para resolver el problema de obtener el número en lugar del texto con el método de extensión de Prise.

public static SelectList ToSelectList<TEnum>(this TEnum enumObj) { var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString()) , Name = e.ToString() }; return new SelectList(values, "Id", "Name", enumObj); }



Sé que llego tarde a la fiesta en esto, pero pensé que podría encontrar útil esta variante, ya que esta también le permite usar cadenas descriptivas en lugar de constantes de enumeración en el menú desplegable. Para hacer esto, decore cada entrada de enumeración con un atributo [System.ComponentModel.Description].

Por ejemplo:

public enum TestEnum { [Description("Full test")] FullTest, [Description("Incomplete or partial test")] PartialTest, [Description("No test performed")] None }

Aquí está mi código:

using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using System.Web.Mvc.Html; using System.Reflection; using System.ComponentModel; using System.Linq.Expressions; ... private static Type GetNonNullableModelType(ModelMetadata modelMetadata) { Type realModelType = modelMetadata.ModelType; Type underlyingType = Nullable.GetUnderlyingType(realModelType); if (underlyingType != null) { realModelType = underlyingType; } return realModelType; } private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } }; public static string GetEnumDescription<TEnum>(TEnum value) { FieldInfo fi = value.GetType().GetField(value.ToString()); DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); if ((attributes != null) && (attributes.Length > 0)) return attributes[0].Description; else return value.ToString(); } public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression) { return EnumDropDownListFor(htmlHelper, expression, null); } public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes) { ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); Type enumType = GetNonNullableModelType(metadata); IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>(); IEnumerable<SelectListItem> items = from value in values select new SelectListItem { Text = GetEnumDescription(value), Value = value.ToString(), Selected = value.Equals(metadata.Model) }; // If the enum is nullable, add an ''empty'' item to the collection if (metadata.IsNullableValueType) items = SingleEmptyItem.Concat(items); return htmlHelper.DropDownListFor(expression, items, htmlAttributes); }

A continuación, puede hacer esto en su vista:

@Html.EnumDropDownListFor(model => model.MyEnumProperty)

¡Espero que esto te ayude!

** EDIT 2014-JAN-23: Microsoft acaba de lanzar MVC 5.1, que ahora tiene una función EnumDropDownListFor. Lamentablemente, no parece respetar el atributo [Descripción], por lo que el código anterior sigue en pie. Consulte la sección Enum en las notas de lanzamiento de Microsoft para MVC 5.1.

Actualización: admite el atributo de Display [Display(Name = "Sample")] , así que uno puede usar eso.

[Actualización: acabo de notar esto y el código parece una versión extendida del código aquí: https://blogs.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums/ , con un par de adiciones. Si es así, la atribución parecería justa ;-)]


Sobre la base de la respuesta de Simon, un enfoque similar es lograr que los valores de Enum se muestren desde un archivo de Recursos, en lugar de hacerlo en un atributo de descripción dentro del Enum mismo. Esto es útil si su sitio necesita ser representado en más de un idioma y si tuviera un archivo de recursos específico para Enums, podría ir un paso más allá y tener solo los valores de Enum, en su Enum y hacer referencia a ellos desde la extensión. una convención como [EnumName] _ [EnumValue] - ¡en última instancia, menos escritura!

La extensión entonces se ve como:

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 = from enumValue in enumValues select new SelectListItem { Text = GetResourceValueForEnumValue(enumValue), Value = ((int)enumValue).ToString(), Selected = enumValue.Equals(metadata.Model) }; return html.DropDownListFor(expression, items, string.Empty, null); } private static string GetResourceValueForEnumValue<TEnum>(TEnum enumValue) { var key = string.Format("{0}_{1}", enumValue.GetType().Name, enumValue); return Enums.ResourceManager.GetString(key) ?? enumValue.ToString(); }

Los recursos en el archivo Enums.Resx se parecen a ItemTypes_Movie: Film

Otra cosa que me gusta hacer es que, en lugar de llamar directamente al método de extensión, prefiero llamarlo con @ Html.EditorFor (x => x.MyProperty), o lo ideal es que tenga todo el formulario, en un solo @ Html.EditorForModel (). Para hacer esto cambio la plantilla de cadena para que se vea así

@using MVCProject.Extensions @{ var type = Nullable.GetUnderlyingType(ViewData.ModelMetadata.ModelType) ?? ViewData.ModelMetadata.ModelType; @(typeof (Enum).IsAssignableFrom(type) ? Html.EnumDropDownListFor(x => x) : Html.TextBoxFor(x => x)) }

Si esto te interesa, pongo una respuesta mucho más detallada aquí en mi blog:

http://paulthecyclist.com/2013/05/24/enum-dropdown/


Una forma muy fácil de hacer esto - sin todas las extensiones que parecen excesivas es la siguiente:

Su enumeración:

public enum SelectedLevel { Level1, Level2, Level3, Level4 }

Dentro de su controlador vincule el Enum a una lista:

List<SelectedLevel> myLevels = Enum.GetValues(typeof(SelectedLevel)).Cast<SelectedLevel>().ToList();

Después de eso tirarlo en un ViewBag:

ViewBag.RequiredLevel = new SelectList(myLevels);

Por último simplemente enlazarlo a la vista:

@Html.DropDownList("selectedLevel", (SelectList)ViewBag.RequiredLevel, new { @class = "form-control" })

Esta es, de lejos, la forma más fácil de encontrar y no requiere ninguna extensión ni nada tan loco.

ACTUALIZACIÓN : Ver comentario Andrews a continuación.


Aquí hay una variación de Martin Faartoft en la que puede colocar etiquetas personalizadas, lo que es bueno para la localización.

public static class EnumHtmlHelper { public static SelectList ToSelectList<TEnum>(this TEnum enumObj, Dictionary<int, string> customLabels) where TEnum : struct, IComparable, IFormattable, IConvertible { var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { Id = e, Name = customLabels.First(x => x.Key == Convert.ToInt32(e)).Value.ToString() }; return new SelectList(values, "Id", "Name", enumObj); } }

Utilizar en la vista:

@Html.DropDownListFor(m => m.Category, Model.Category.ToSelectList(new Dictionary<int, string>() { { 1, ContactResStrings.FeedbackCategory }, { 2, ContactResStrings.ComplainCategory }, { 3, ContactResStrings.CommentCategory }, { 4, ContactResStrings.OtherCategory } }), new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.Category)


Esta es mi versión del método de ayuda. Yo uso esto:

var values = from int e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };

En lugar de eso:

var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString()) , Name = e.ToString() };

Aquí está:

public static SelectList ToSelectList<TEnum>(this TEnum self) where TEnum : struct { if (!typeof(TEnum).IsEnum) { throw new ArgumentException("self must be enum", "self"); } Type t = typeof(TEnum); var values = from int e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) }; return new SelectList(values, "ID", "Name", self); }


He hecho lo siguiente y funciona con éxito:

  • En el view.cshtml:

@model MyModel.cs

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

  • En el modelo: MyModel.cs

public ItemTypes MyItemType { get; set; }


Si desea agregar soporte de localización, simplemente cambie el método s.toString () a algo como esto:

ResourceManager rManager = new ResourceManager(typeof(Resources)); var dayTypes = from OperatorCalendarDay.OperatorDayType s in Enum.GetValues(typeof(OperatorCalendarDay.OperatorDayType)) select new { ID = s, Name = rManager.GetString(s.ToString()) };

Aquí, el tipo de (Recursos) es el recurso que desea cargar, y luego obtiene la Cadena localizada, también útil si su enumerador tiene valores con varias palabras.


También puedes usar mi HtmlHelpers personalizado en Griffin.MvcContrib. El siguiente código:

@Html2.CheckBoxesFor(model => model.InputType) <br /> @Html2.RadioButtonsFor(model => model.InputType) <br /> @Html2.DropdownFor(model => model.InputType) <br />

Genera:

https://github.com/jgauffin/griffin.mvccontrib


@Simon Goldstone: Gracias por su solución, se puede aplicar perfectamente en mi caso. El único problema es que tuve que traducirlo a VB. Pero ahora está hecho y para ahorrar el tiempo de otras personas (en caso de que lo necesiten) lo pongo aquí:

Imports System.Runtime.CompilerServices Imports System.ComponentModel Imports System.Linq.Expressions Public Module HtmlHelpers Private Function GetNonNullableModelType(modelMetadata As ModelMetadata) As Type Dim realModelType = modelMetadata.ModelType Dim underlyingType = Nullable.GetUnderlyingType(realModelType) If Not underlyingType Is Nothing Then realModelType = underlyingType End If Return realModelType End Function Private ReadOnly SingleEmptyItem() As SelectListItem = {New SelectListItem() With {.Text = "", .Value = ""}} Private Function GetEnumDescription(Of TEnum)(value As TEnum) As String Dim fi = value.GetType().GetField(value.ToString()) Dim attributes = DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute()) If Not attributes Is Nothing AndAlso attributes.Length > 0 Then Return attributes(0).Description Else Return value.ToString() End If End Function <Extension()> Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TEnum))) As MvcHtmlString Return EnumDropDownListFor(htmlHelper, expression, Nothing) End Function <Extension()> Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TEnum)), htmlAttributes As Object) As MvcHtmlString Dim metaData As ModelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData) Dim enumType As Type = GetNonNullableModelType(metaData) Dim values As IEnumerable(Of TEnum) = [Enum].GetValues(enumType).Cast(Of TEnum)() Dim items As IEnumerable(Of SelectListItem) = From value In values Select New SelectListItem With { .Text = GetEnumDescription(value), .Value = value.ToString(), .Selected = value.Equals(metaData.Model) } '' If the enum is nullable, add an ''empty'' item to the collection If metaData.IsNullableValueType Then items = SingleEmptyItem.Concat(items) End If Return htmlHelper.DropDownListFor(expression, items, htmlAttributes) End Function End Module

Fin Lo usas así:

@Html.EnumDropDownListFor(Function(model) (model.EnumField))


He encontrado una respuesta https://blogs.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums/ . Sin embargo, algunos de mis enums tienen [Description(...)]atributos, así que modifiqué el código para proporcionar soporte para eso

enum Abc { [Description("Cba")] Abc, Def } public static MvcHtmlString EnumDropDownList<TEnum>(this HtmlHelper htmlHelper, string name, TEnum selectedValue) { IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum)) .Cast<TEnum>(); List<SelectListItem> items = new List<SelectListItem>(); foreach (var value in values) { string text = value.ToString(); var member = typeof(TEnum).GetMember(value.ToString()); if (member.Count() > 0) { var customAttributes = member[0].GetCustomAttributes(typeof(DescriptionAttribute), false); if (customAttributes.Count() > 0) { text = ((DescriptionAttribute)customAttributes[0]).Description; } } items.Add(new SelectListItem { Text = text, Value = value.ToString(), Selected = (value.Equals(selectedValue)) }); } return htmlHelper.DropDownList( name, items ); }

Espero que ayude.


Otra solución para este método de extensión: la versión actual no seleccionó el valor actual de la enumeración. Arreglé la última línea:

public static SelectList ToSelectList<TEnum>(this TEnum enumObj) where TEnum : struct { if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj"); var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() }; return new SelectList(values, "ID", "Name", ((int)Enum.Parse(typeof(TEnum), enumObj.ToString())).ToString()); }


Terminé creando métodos de extensión para hacer lo que es esencialmente la respuesta de aceptación aquí. La última mitad de la Gist trata de Enum específicamente.

https://gist.github.com/3813767


@Html.DropDownListFor(model => model.MaritalStatus, new List<SelectListItem> { new SelectListItem { Text = "----Select----", Value = "-1" }, new SelectListItem { Text = "Marrid", Value = "M" }, new SelectListItem { Text = "Single", Value = "S" } })


@Html.DropDownListFor(model => model.Type, Enum.GetNames(typeof(Rewards.Models.PropertyType)).Select(e => new SelectListItem { Text = e }))


@Html.DropdownListFor(model=model->Gender,new List<SelectListItem> { new ListItem{Text="Male",Value="Male"}, new ListItem{Text="Female",Value="Female"}, new ListItem{Text="--- Select -----",Value="-----Select ----"} } )