【发布时间】:2011-03-30 04:50:18
【问题描述】:
我有一个 asp.net-mvc 网页,我想显示一个基于枚举的下拉列表。我想显示每个枚举项的文本,id 是与枚举关联的 int 值。有什么优雅的方式来进行这种转换吗?
【问题讨论】:
-
马克西姆 Vi 的答案。应该是正确的答案。
标签: c# asp.net-mvc enums selectlistitem
我有一个 asp.net-mvc 网页,我想显示一个基于枚举的下拉列表。我想显示每个枚举项的文本,id 是与枚举关联的 int 值。有什么优雅的方式来进行这种转换吗?
【问题讨论】:
标签: c# asp.net-mvc enums selectlistitem
在 Asp.Net Core 中,只需使用:
<select asp-for="MyEnum" asp-items="Html.GetEnumSelectList(typeof(MyEnum))"></select>
或者
创建助手
public static class EnumHelper
{
public static IEnumerable<SelectListItem> GetEnumSelectList<TEnum>(bool isNullable = false)
where TEnum : struct
{
IList<SelectListItem> selectLists = Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Select(c => new SelectListItem()
{
Text = GetDisplayName(c),
Value = c.ToString()
}).ToList();
if (isNullable)
{
selectLists.Add(new SelectListItem());
}
return selectLists.OrderBy(c => c.Value);
}
public static string GetDisplayName<TEnum>(TEnum enumVal)
{
DisplayAttribute attr = GetAttribute<DisplayAttribute>(enumVal);
if (attr != null)
{
return attr.Name;
}
return enumVal?.ToString() ?? string.Empty;
}
public static TEnum GetAttribute<TEnum>(object enumVal) where TEnum : Attribute
{
if (enumVal == null)
{
return default;
}
Type type = enumVal.GetType();
MemberInfo[] memInfo = type.GetMember(enumVal.ToString());
if (memInfo.Length == 0)
{
return null;
}
object[] attributes = memInfo[0].GetCustomAttributes(typeof(TEnum), false);
return attributes.Length > 0 ? (TEnum)attributes[0] : null;
}
}
使用
@using MyClass.Helpers;
<select asp-for="MyEnum" asp-items="EnumHelper.GetEnumSelectList<MyEnum>(true)">/select>
【讨论】:
使用我的扩展方法非常简单。它还允许您提供选项,例如添加占位符、分组和禁用某些值或组。试试看吧。
enum Color
{
Blue,
[Category("Light")]
[DisplayName("Light Blue")]
LBlue,
[Category("Dark")]
[DisplayName("Dark Blue")]
DBlue,
Red,
[Category("Dark")]
[DisplayName("Dark Red")]
DRed,
[Category("Light")]
[DisplayName("Light Red")]
LRed,
Green,
[Category("Dark")]
[DisplayName("Dark Green")]
DGreen,
[Category("Light")]
[DisplayName("Light Green")]
LGreen
}
var list = typeof(Color).ToSelectList();
//or with custom options
var list = typeof(Color).ToSelectList(new SelectListOptions { Placeholder = "Please Select A Color"});
【讨论】:
我使用了 Html Helper 类中的 GetEnumSelectList
<select asp-for="MyProperty" class="form-control" asp-items="@Html.GetEnumSelectList<MyEnum>()" ></select>
【讨论】:
我使用可以重复使用的静态方法来完成这项工作。
public static IEnumerable<SelectListItem> EnumToSelectList<T>()
{
return (Enum.GetValues(typeof(T)).Cast<T>().Select(
e => new SelectListItem() { Text = e.ToString(), Value = e.ToString() })).ToList();
}
【讨论】:
从 MVC 5.1 开始,如果您需要在视图中填充 select 选项,最优雅的方法是使用 Html 助手的 EnumDropDownListFor 方法:
@Html.EnumDropDownListFor(m => m.MyEnumProperty,new { @class="form-control"})
或控制器中 EnumHelper 的 GetSelectList 方法:
var enumList = EnumHelper.GetSelectList(typeof (MyEnum));
【讨论】:
您可以使用 LINQ:
Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Select(v => new SelectListItem {
Text = v.ToString(),
Value = ((int)v).ToString()
}).ToList();
【讨论】:
您可以使用Enum.GetNames() 获取包含枚举项名称的字符串数组。如果您的项目名称是用户友好的,那么这可能就足够了。否则,您可以创建自己的 GetName() 方法,该方法将为每个项目返回一个好听的名称。
或者 - 如果枚举永远不会(或很少)更改,您可以创建一个直接将硬编码项目添加到下拉列表的方法。这可能更有效(如果这对您很重要)。
【讨论】:
现在我使用了Tuple<string, string>,但您可以将其转换为使用任何东西:
var values = Enum.GetValues(typeof(DayOfWeek))
.Cast<DayOfWeek>()
.Select(d => Tuple.Create(((int)d).ToString(), d.ToString()))
.ToList()
【讨论】: