我正在尝试使用Html。下拉列表扩展方法,但不知道如何与枚举一起使用它。
假设我有一个这样的枚举:
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
我如何去创建一个下拉与这些值使用Html。下拉列表扩展方法?
或者我最好的办法是简单地创建一个for循环并手动创建Html元素?
我正在尝试使用Html。下拉列表扩展方法,但不知道如何与枚举一起使用它。
假设我有一个这样的枚举:
public enum ItemTypes
{
Movie = 1,
Game = 2,
Book = 3
}
我如何去创建一个下拉与这些值使用Html。下拉列表扩展方法?
或者我最好的办法是简单地创建一个for循环并手动创建Html元素?
当前回答
下面是一个更好的封装解决方案:
https://www.spicelogic.com/Blog/enum-dropdownlistfor-asp-net-mvc-5
这是你的模型:
示例用法:
生成的界面:
生成的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();
}
}
其他回答
您希望使用类似Enum的东西。getvalue
下面是一个更好的封装解决方案:
https://www.spicelogic.com/Blog/enum-dropdownlistfor-asp-net-mvc-5
这是你的模型:
示例用法:
生成的界面:
生成的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();
}
}
对于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及更低版本
我把Rune的答案变成了一个扩展方法:
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();
使用MyApp。常见的
我想以一种不同的方式回答这个问题,用户不需要在控制器或Linq表达式中做任何事情。这种方式……
我有一个ENUM
public enum AccessLevelEnum
{
/// <summary>
/// The user cannot access
/// </summary>
[EnumMember, Description("No Access")]
NoAccess = 0x0,
/// <summary>
/// The user can read the entire record in question
/// </summary>
[EnumMember, Description("Read Only")]
ReadOnly = 0x01,
/// <summary>
/// The user can read or write
/// </summary>
[EnumMember, Description("Read / Modify")]
ReadModify = 0x02,
/// <summary>
/// User can create new records, modify and read existing ones
/// </summary>
[EnumMember, Description("Create / Read / Modify")]
CreateReadModify = 0x04,
/// <summary>
/// User can read, write, or delete
/// </summary>
[EnumMember, Description("Create / Read / Modify / Delete")]
CreateReadModifyDelete = 0x08,
/*/// <summary>
/// User can read, write, or delete
/// </summary>
[EnumMember, Description("Create / Read / Modify / Delete / Verify / Edit Capture Value")]
CreateReadModifyDeleteVerify = 0x16*/
}
现在我可以使用这个enum简单地创建一个下拉列表。
@Html.DropDownList("accessLevel",new SelectList(AccessLevelEnum.GetValues(typeof(AccessLevelEnum))),new { @class = "form-control" })
OR
@Html.DropDownListFor(m=>m.accessLevel,new SelectList(AccessLevelEnum.GetValues(typeof(AccessLevelEnum))),new { @class = "form-control" })
如果你想让一个索引被选中,那么试试这个
@Html.DropDownListFor(m=>m.accessLevel,new SelectList(AccessLevelEnum.GetValues(typeof(AccessLevelEnum)) , AccessLevelEnum.NoAccess ),new { @class = "form-control" })
这里我使用了AccessLevelEnum。NoAccess作为默认选择下拉菜单的额外参数。
根据Simon的回答,类似的方法是从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();
}
枚举中的资源。Resx文件看起来像这样 ItemTypes_Movie:电影
我喜欢做的另一件事是,与其直接调用扩展方法,不如使用@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/