我已经为EditorFor和DisplayFor帮助方法创建了几个MVC模板,以便按照我想要的方式使用Twitter Bootstrap框架来设置样式。我现在有一个工作解决方案,我需要的所有位,但我想概括我设置的一个部分,以显示状态列表。我有一个州枚举(包含所有美国州的列表),我在下拉列表中显示用户地址。我使用[DataType]属性让MVC使用我的State.cshtml模板。
[Required]
[Display(Name = "State")]
[DataType("State")]
public State State { get; set; }
所以它工作得很好,但我想改变它,以便我可以做一些像DataType(“Enum”)或其他一些方法来为所有枚举一般地点击这个模板。
模板如下所示:
@using System
@using System.Linq
@using Beno.Web.Helpers
@using TC.Util
@model Beno.Model.Enums.State
<div class="control-group">
@Html.LabelFor(m => m, new {@class = "control-label{0}".ApplyFormat(ViewData.ModelMetadata.IsRequired ? " required" : "")})
<div class="controls">
<div class="input-append">
@Html.EnumDropDownListFor(m => m)
<span class="add-on">@(new MvcHtmlString("{0}".ApplyFormat(ViewData.ModelMetadata.IsRequired ? " <i class=\"icon-star\"></i>" : "")))</span>
</div>
@Html.ValidationMessageFor(m => m, null, new {@class = "help-inline"})
</div>
</div>
EnumDropDownListFor是我之前发布的一个帮助方法,它通常用于任何枚举。我不知道的是我如何更改此模板以将通用枚举作为模型对象?
更新:为了完整性,我包含了EnumDropDownListFor方法的列表:
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null) where TProperty : struct, IConvertible
{
if (!typeof(TProperty).IsEnum)
throw new ArgumentException("TProperty must be an enumerated type");
var selectedValue = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData).Model.ToString();
var selectList = new SelectList(from value in EnumHelper.GetValues<TProperty>()
select new SelectListItem
{
Text = value.ToDescriptionString(),
Value = value.ToString()
}, "Value", "Text", selectedValue);
return htmlHelper.DropDownListFor(expression, selectList, htmlAttributes);
}
将模型类型更改为Enum会在调用helper方法的行上产生以下错误:
CS0453: The type 'System.Enum' must be a non-nullable value type in order to use it as parameter 'TProperty' in the generic type or method 'Beno.Web.Helpers.ControlHelper.EnumDropDownListFor<TModel,TProperty>(System.Web.Mvc.HtmlHelper<TModel>, System.Linq.Expressions.Expression<System.Func<TModel,TProperty>>, object)'
然后,如果我删除了检查,如果TProperty是枚举,结构是约束,我在我试图得到枚举值的行上得到编译错误:
System.ArgumentException: Type 'Enum' is not an enum
我想知道我是不是可以做我在这里尝试的事情。
答案 0 :(得分:1)
您可以创建一个EditorTemplate Enum.cshtml
你所要做的就是改变这一行:
@model Beno.Model.Enums.State
为此:
@model System.Enum
然后,您就可以使用任何Enum
。
catch:引擎无法推断项目的基类,因此,TestEnum不会被分配Enum模板,因此您必须明确地调用它:
@Html.EditorFor(model => model.EnumValue, "Enum")
答案 1 :(得分:0)
不确定我是否理解你的意思,但试试这个:
@Html.DropDownListFor(model => model.EnumName, new SelectList(Enum.GetValues(typeof(Namespace.Models.EnumName))))
EnumName =您案件中的州。
我已经使用上面的内容使用Twitter Bootstrap将枚举列入下拉列表。
答案 2 :(得分:0)
我也一直在努力实现这一目标。
您是否希望能够在所有模型中为所有Enum类型使用一个模板。 这样,您可以在EditorTemplates文件夹中使用枚举模板,以便将其显示为下拉列表。
您遇到的问题是您的模板在TModel和TProperty中传递了System.Enum的类型
Expression<Func<TModel, TProperty>> expression
然后,当您执行以下操作时,TProperty的类型为System.Enum,而不是Beno.Model.Enums.State
EnumHelper.GetValues<TProperty>()
为了解决这个问题,我不打算看看TProperty,因为它没有给我正确的类型。
相反,我查看metadata.ModelType。
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
这给了我正确的类型但你不能在Covariance Derived类中使用它们
EnumHelper.GetValue<metadata.ModelType> //This does not work.
所以我重写了身体,不使用任何泛型。
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var values = Enum.GetValues(metadata.ModelType);
List<SelectListItem> items = new List<SelectListItem>();
foreach (var v in values)
{
items.Add(new SelectListItem
{
Text = Regex.Replace(v.ToString(), "([A-Z][a-z])", " $1").Trim(),
Value = v.ToString(),
Selected = v.Equals(metadata.Model)
});
}
return htmlHelper.DropDownListFor(expression, items);
}
您可能需要更改方法签名以包含htmlattributes。
答案 3 :(得分:0)
正如其他人所说,编写自定义帮助程序是可行的方法。这正是在TwitterBootstrapMVC中所做的。在其他助手中,它有一个助手DropDownListFromEnumFor(...)
,您可以这样使用:
@Html.Bootstrap().DropDownListFromEnumFor(m => m.SomeEnum)
或
@Html.Bootstrap().DropDownListFromEnum("SomeEnum")
关于BMVC的一个很酷的事情是,您可以使用扩展方法自定义下拉列表,其中一些是常规html,另一些是Bootstrap特定的。以下是其中一些:
@(f.ControlGroup().DropDownListFromEnumFor(m => m.SomeEnum)
.Append("something")
.AppendIcon("glyphicon glyphicon-chevron-right")
.Class("cool-dd")
.OptionLabel("-- Select --")
.Tooltip("cool tooltip"))
哦,是的,上面的示例将生成完整的控制组 - 输入,标签和验证消息。
免责声明:我是TwitterBootstrapMVC的作者