我跟随this blog可以从ViewModels中需要的几个枚举创建DropDownLists。如何添加 - 从DropDownList中选择一些东西 - 从枚举中创建
到目前为止,我的代码看起来像这样:
public static class HtmlDropDownExtensions
{
private static readonly SelectListItem [] SingleEmptyItem = new[]{new SelectListItem{Text = string.Empty, Value = string.Empty}};
public static MvcHtmlString EnumDropDownList<TEnum>(this HtmlHelper htmlHelper, string modelPropertyName, TEnum selectedValue)
{
Type baseEnumType = Enum.GetUnderlyingType(typeof(TEnum));
IEnumerable<TEnum> values = Enum.GetValues(typeof (TEnum)).Cast<TEnum>();
IEnumerable<SelectListItem> items = GetSelectListItems(values, selectedValue, baseEnumType);
return htmlHelper.DropDownList(modelPropertyName, items);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
Type enumType = GetNonNullableModelType(metadata);
Type baseEnumType = Enum.GetUnderlyingType(enumType);
IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>();
IEnumerable<SelectListItem> items = GetSelectListItems(values, metadata.Model, baseEnumType);
if (metadata.IsNullableValueType)
items = SingleEmptyItem.Concat(items);
return htmlHelper.DropDownListFor(expression, items);
}
private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
Type realModelType = modelMetadata.ModelType;
Type underlyingType = Nullable.GetUnderlyingType(realModelType);
if(underlyingType != null)
realModelType = underlyingType;
return realModelType;
}
private static IEnumerable<SelectListItem> GetSelectListItems<TEnum>(IEnumerable<TEnum> values, object selectedValue, Type underlyingType)
{
return from value in values
select new SelectListItem
{
Text = value.ToString(),
Value = Convert.ChangeType(value, underlyingType).ToString(),
Selected = (value.Equals(selectedValue))
};
}
}
现在我需要的是能够有一个提示用户的第一选择,以选择一个选项,是因为空白或不选择什么字段是必需的,并且不能有任何默认值。
更新: 我在想,也许“EnumDropDownList”的方法也可以在创建的DropDownList并返回字符串前加空SelectListItem。我还没有尝试过,但我认为MVC工程将尝试将其绑定到ViewModel时会出现错误,因为无法将该值解析到ViewModel的枚举属性中。
感谢您的帮助。
在列表的开始处插入默认项:dropdownlist.Insert(0,defaultItem); – MrFox
@MFFOX:对不起,纠正我,如果我错了,但我认为这只会在Web窗体解决方案,而不是在MVC之一。 –