ASP.NET MVC의 열거 형에서 드롭 다운 목록을 만드는 방법은 무엇입니까?
Html.DropDownList
확장 메서드 를 사용하려고하는데 열거 형과 함께 사용하는 방법을 알 수 없습니다.
다음과 같은 열거가 있다고 가정 해 보겠습니다.
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
Html.DropDownList
확장 방법을 사용하여 이러한 값으로 드롭 다운을 만드는 방법은 무엇입니까?
아니면 단순히 for 루프를 만들고 Html 요소를 수동으로 만드는 것이 최선의 방법입니까?
MVC v5.1의 경우 Html.EnumDropDownListFor를 사용하십시오.
@Html.EnumDropDownListFor(
x => x.YourEnumField,
"Select My Type",
new { @class = "form-control" })
MVC v5의 경우 EnumHelper 사용
@Html.DropDownList("MyType",
EnumHelper.GetSelectList(typeof(MyType)) ,
"Select My Type",
new { @class = "form-control" })
MVC 5 이하
나는 룬의 대답을 확장 방법으로 굴렸다.
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);
}
}
}
이를 통해 다음을 작성할 수 있습니다.
ViewData["taskStatus"] = task.Status.ToSelectList();
으로 using MyApp.Common
나는 이것에 대해 파티에 늦었다는 것을 알고 있지만, 드롭 다운에서 열거 상수 대신 설명 문자열을 사용할 수 있기 때문에이 변형이 유용하다고 생각할 수 있습니다. 이렇게하려면 [System.ComponentModel.Description] 속성을 사용하여 각 열거 항목을 장식합니다.
예를 들면 :
public enum TestEnum
{
[Description("Full test")]
FullTest,
[Description("Incomplete or partial test")]
PartialTest,
[Description("No test performed")]
None
}
내 코드는 다음과 같습니다.
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);
}
그런 다음보기에서이를 수행 할 수 있습니다.
@Html.EnumDropDownListFor(model => model.MyEnumProperty)
도움이 되었기를 바랍니다.
** 2014-JAN-23 편집 : Microsoft는 이제 EnumDropDownListFor 기능이있는 MVC 5.1을 출시했습니다. 슬프게도 [Description] 속성을 존중하지 않는 것처럼 보이므로 위의 코드는 그대로 유지 됩니다. MVC 5.1에 대한 Microsoft 릴리스 노트의 Enum 섹션을 참조 하세요 .
업데이트 : 디스플레이 속성을 지원 [Display(Name = "Sample")]
하므로 사용할 수 있습니다.
[업데이트-방금 이것을 발견했으며 코드는 여기에서 코드의 확장 버전처럼 보입니다 : https://blogs.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a- dropdownlist-helper-for-enums / , 몇 가지 추가 사항이 있습니다. 그렇다면 귀속이 공정 해 보일 것입니다 ;-)]
에서 ASP.NET MVC 5.1 , 그들은 추가 EnumDropDownListFor()
도우미, 그래서 사용자 지정 확장에 대한 필요를 :
모델 :
public enum MyEnum
{
[Display(Name = "First Value - desc..")]
FirstValue,
[Display(Name = "Second Value - desc...")]
SecondValue
}
보기 :
@Html.EnumDropDownListFor(model => model.MyEnum)
태그 도우미 (ASP.NET MVC 6) 사용 :
<select asp-for="@Model.SelectedValue" asp-items="Html.GetEnumSelectList<MyEnum>()">
나는 같은 문제에 부딪 혔고이 질문을 발견했고 Ash가 제공 한 해결책이 내가 찾던 것이 아니라고 생각했습니다. HTML을 직접 만들어야한다는 것은 기본 제공 Html.DropDownList()
기능에 비해 유연성이 낮다는 것을 의미 합니다.
C # 3 등이이 작업을 매우 쉽게 만듭니다. 나는 enum
전화가있다 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);
이것은 SelectList
보기에서 익숙한 것처럼 사용할 수 있는 좋은 ol ' 을 만듭니다 .
<td><b>Status:</b></td><td><%=Html.DropDownList("taskStatus")%></td></tr>
익명 형식과 LINQ는이를 훨씬 더 우아한 IMHO로 만듭니다. 의도 한 건 아니에요, 애쉬 :)
다음은 더 나은 캡슐화 된 솔루션입니다.
https://www.spicelogic.com/Blog/enum-dropdownlistfor-asp-net-mvc-5
여기에 모델이 있다고 말하십시오.
샘플 사용법 :
생성 된 UI :
그리고 생성 된 HTML
도우미 확장 소스 코드 스냅 샷 :
내가 제공 한 링크에서 샘플 프로젝트를 다운로드 할 수 있습니다.
편집 : 코드는 다음과 같습니다.
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();
}
}
Html.DropDownListFor에는 IEnumerable 만 필요하므로 Prise 솔루션의 대안은 다음과 같습니다. 이렇게하면 다음과 같이 간단히 작성할 수 있습니다.
@Html.DropDownListFor(m => m.SelectedItemType, Model.SelectedItemType.ToSelectList())
[SelectedItemType이 ItemTypes 유형의 모델에 대한 필드이고 모델이 널이 아닌 경우]
또한 typeof (T) 대신 enumValue.GetType ()을 사용할 수 있으므로 확장 메서드를 실제로 일반화 할 필요가 없습니다.
편집 : 여기에 Simon의 솔루션을 통합하고 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();
}
}
그래서 간단하고 쉬운 방법을 찾고 있다면 확장 기능없이 ..
<%= Html.DropDownListFor(x => x.CurrentAddress.State, new SelectList(Enum.GetValues(typeof(XXXXX.Sites.YYYY.Models.State))))%>
여기서 XXXXX.Sites.YYYY.Models.State는 열거 형입니다.
아마도 도우미 기능을 수행하는 것이 더 좋지만 시간이 부족하면 작업이 완료됩니다.
상품 및 룬의 답변을 확장하여 선택 목록 항목의 값 속성을 문자열 값이 아닌 열거 유형의 정수 값에 매핑하려면 다음 코드를 사용하세요.
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);
}
각 Enumeration 값을 TEnum 객체로 처리하는 대신 객체로 처리 한 다음 정수로 캐스팅하여 박싱되지 않은 값을 얻을 수 있습니다.
참고 : 또한이 확장이 구조체 (Enum의 기본 형식)에만 사용할 수있는 형식을 제한하는 제네릭 형식 제약 조건과 전달 된 구조체가 실제로 Enum인지 확인하는 런타임 형식 유효성 검사를 추가했습니다.
업데이트 10/23/12 : 기본 유형에 대한 일반 유형 매개 변수를 추가하고 .NET 4 이상에 영향을 미치는 컴파일되지 않은 문제를 수정했습니다.
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);
}
내가 찾은 최고의 솔루션은 이 블로그 를 Simon Goldstone의 답변 과 결합하는 것이 었습니다 .
이를 통해 모델에서 열거 형을 사용할 수 있습니다. 본질적으로 아이디어는 정수 속성과 열거 형을 사용하고 정수 속성을 에뮬레이트하는 것입니다.
그런 다음 표시 텍스트로 모델에 주석을 달기 위해 [System.ComponentModel.Description] 특성을 사용하고 뷰에서 "EnumDropDownListFor"확장을 사용합니다.
이것은 뷰와 모델 모두를 매우 읽기 쉽고 유지 관리 할 수있게합니다.
모델:
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; }
}
전망:
@using MyProject.Extensions
{
//...
@Html.EnumDropDownListFor(model => model.CuriousQuestion)
//...
}
확장 ( 완전성을 위해 여기에 포함 된 Simon Goldstone의 답변 에서 직접 ) :
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);
}
}
}
이 작업을 수행하는 매우 쉬운 방법-과도하게 보이는 모든 확장 기능 없이는 다음과 같습니다.
열거 형 :
public enum SelectedLevel
{
Level1,
Level2,
Level3,
Level4
}
컨트롤러 내부에서 Enum을 List에 바인딩합니다.
List<SelectedLevel> myLevels = Enum.GetValues(typeof(SelectedLevel)).Cast<SelectedLevel>().ToList();
그 후 ViewBag에 던져 넣으십시오.
ViewBag.RequiredLevel = new SelectList(myLevels);
마지막으로 View에 바인딩하기 만하면됩니다.
@Html.DropDownList("selectedLevel", (SelectList)ViewBag.RequiredLevel, new { @class = "form-control" })
이것은 내가 찾은 가장 쉬운 방법이며 확장이나 미친 것이 필요하지 않습니다.
업데이트 : 아래 Andrews 의견을 참조하십시오.
당신은 다음과 같은 것을 사용하고 싶습니다. Enum.GetValues
@Html.DropDownListFor(model => model.Type, Enum.GetNames(typeof(Rewards.Models.PropertyType)).Select(e => new SelectListItem { Text = e }))
Enum int
값을 ID로 사용하도록 변경된 Rune & Prize 답변 입니다.
샘플 열거 형 :
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
연장 방법 :
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()));
}
사용 예 :
<%= Html.DropDownList("MyEnumList", ItemTypes.Game.ToSelectList()) %>
Extension 메서드가 포함 된 네임 스페이스를 가져 오는 것을 잊지 마십시오.
<%@ Import Namespace="MyNamespace.LocationOfExtensionMethod" %>
생성 된 HTML 샘플 :
<select id="MyEnumList" name="MyEnumList">
<option value="1">Movie</option>
<option selected="selected" value="2">Game</option>
<option value="3">Book </option>
</select>
를 호출하는 데 사용하는 항목이 ToSelectList
선택한 항목입니다.
이것은 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)
이제이 기능은 MVC 5.1에서 기본적으로 지원됩니다. @Html.EnumDropDownListFor()
다음 링크를 확인하십시오.
https://docs.microsoft.com/en-us/aspnet/mvc/overview/releases/mvc51-release-notes#Enum
위의 투표에 따라 수요가 많은 기능을 구현하는 데 Microsoft가 5 년이 걸린 것은 정말 아쉽습니다!
Simon의 대답을 기반으로 유사한 접근 방식은 Enum 자체 내의 설명 속성 대신 Resource 파일에서 표시 할 Enum 값을 가져 오는 것입니다. 이는 사이트를 두 개 이상의 언어로 렌더링해야하는 경우에 유용하며 Enum에 대한 특정 리소스 파일이있는 경우 한 단계 더 나아가 Enum에 Enum 값만 포함하고 확장에서 참조 할 수 있습니다. [EnumName] _ [EnumValue]와 같은 규칙-궁극적으로 입력 횟수가 줄어 듭니다!
확장은 다음과 같습니다.
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();
}
ItemTypes_Movie와 같은 Enums.Resx 파일의 리소스 : Film
제가 좋아하는 또 다른 한 가지는 확장 메서드를 직접 호출하는 대신 @ Html.EditorFor (x => x.MyProperty)를 사용하여 호출하거나 이상적으로는 하나의 깔끔한 @ 형식으로 전체 형식을 갖는 것입니다. Html.EditorForModel (). 이렇게하려면 문자열 템플릿을 다음과 같이 변경합니다.
@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))
}
관심이 있으시면 여기에 제 블로그에 훨씬 더 자세한 답변을 올렸습니다.
http://paulthecyclist.com/2013/05/24/enum-dropdown/
나는 파티에 정말 늦었지만, 그만한 가치가있는이 주제에 대해 블로그를 작성하여 EnumHelper
매우 쉽게 변형 할 수 있는 수업을 만들었습니다 .
http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23
컨트롤러에서 :
//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);
보기에서 :
@Html.DropDownList("DropDownList")
@* OR *@
@Html.DropDownListFor(m => m.Property, ViewBag.DropDownList as SelectList, null)
도우미 클래스 :
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() });
}
}
.NET Core에서는 다음을 사용할 수 있습니다.
@Html.DropDownListFor(x => x.Foo, Html.GetEnumSelectList<MyEnum>())
나는 이것에 대해 매우 늦었지만 Unconstrained Melody NuGet 패키지 (Jon Skeet의 멋진 작은 라이브러리) 를 추가하고 싶다면 한 줄의 코드 로이 작업을 수행하는 정말 멋진 방법을 찾았습니다 .
이 솔루션은 다음과 같은 이유로 더 좋습니다.
- (제네릭 유형 제약을 통해) 값이 실제로 열거 형 값 (Unconstrained Melody로 인해)인지 확인합니다.
- Unconstrained Melody로 인해 불필요한 권투를 피합니다.
- Unconstrained Melody로 인해 모든 호출에서 리플렉션 사용을 피하기 위해 모든 설명을 캐시합니다.
- 다른 솔루션보다 코드가 적습니다!
이 작업을 수행하는 단계는 다음과 같습니다.
- 패키지 관리자 콘솔에서 "Install-Package UnconstrainedMelody"
다음과 같이 모델에 속성을 추가합니다.
//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() }); } }
이제 모델에 SelectListItem 목록이 노출되었으므로이 속성을 소스로 사용하여 @ Html.DropDownList 또는 @ Html.DropDownListFor를 사용할 수 있습니다.
여기 에서 답을 찾았 습니다 . 그러나 일부 열거 형에는 [Description(...)]
속성이 있으므로 이에 대한 지원을 제공하기 위해 코드를 수정했습니다.
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
);
}
도움이 되었기를 바랍니다.
이 확장 방법에 대한 또 다른 수정 사항-현재 버전은 열거 형의 현재 값을 선택하지 않았습니다. 마지막 줄을 수정했습니다.
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());
}
지역화 지원을 추가하려면 s.toString () 메서드를 다음과 같이 변경하십시오.
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()) };
여기에서 typeof (Resources)는로드하려는 리소스이고 현지화 된 문자열을 가져옵니다. 열거 자에 여러 단어가있는 값이있는 경우에도 유용합니다.
이것은 내 버전의 도우미 메서드입니다. 나는 이것을 사용한다 :
var values = from int e in Enum.GetValues(typeof(TEnum))
select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) };
그것 대신에:
var values = from TEnum e in Enum.GetValues(typeof(TEnum))
select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString())
, Name = e.ToString() };
여기있어:
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);
}
Griffin.MvcContrib에서 내 사용자 지정 HtmlHelpers를 사용할 수도 있습니다. 다음 코드 :
@Html2.CheckBoxesFor(model => model.InputType) <br />
@Html2.RadioButtonsFor(model => model.InputType) <br />
@Html2.DropdownFor(model => model.InputType) <br />
생성 :
https://github.com/jgauffin/griffin.mvccontrib
@Simon Goldstone : 귀하의 솔루션에 감사드립니다. 제 경우에 완벽하게 적용될 수 있습니다. 유일한 문제는 VB로 번역해야한다는 것입니다. 그러나 이제 완료되었으며 다른 사람들의 시간을 절약하기 위해 (필요한 경우) 여기에 넣습니다.
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
끝 다음과 같이 사용합니다.
@Html.EnumDropDownListFor(Function(model) (model.EnumField))
나는 본질적으로 여기에서 수락 대답을 수행하기 위해 확장 메서드를 생성했습니다. Gist의 마지막 절반은 특별히 Enum을 다룹니다.
https://gist.github.com/3813767
@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 ----"}
}
)
@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" }
})
여기 Martin Faartoft 변형으로 현지화에 적합한 맞춤 라벨을 넣을 수 있습니다.
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);
}
}
보기에서 사용 :
@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)
'IT박스' 카테고리의 다른 글
CSS로 이미지 크기를 비례 적으로 조정 하시겠습니까? (0) | 2020.10.02 |
---|---|
파이썬에서 여러 생성자를 갖는 깔끔하고 파이썬적인 방법은 무엇입니까? (0) | 2020.10.02 |
컨텍스트로 getApplication ()을 사용하여 "창을 추가 할 수 없습니다. 토큰 null은 응용 프로그램에 대한 것이 아닙니다."를 표시하는 대화 상자 (0) | 2020.10.02 |
os / path 형식에 관계없이 경로에서 파일 이름 추출 (0) | 2020.10.02 |
Spring Framework에서 @Inject와 @Autowired의 차이점은 무엇입니까? (0) | 2020.10.02 |