15

我对当前的 DropDownList 实现不满意,因为我无法对选项标签做太多事情(仅支持选定、文本和值)。我想自己做一个我可以在个别选项上设置禁用和其他东西的地方。

目前我正在通过 javascript 更改选项,但我认为这样做有点笨拙,我宁愿只渲染正确的 html 开始。

我知道我可以制作一个使用 select 和 option 标记的模板,并根据需要制作选项 - 但是普通的 DropDownList 扩展会添加东西 val 东西和一个特定的名称和 ID,我猜这是为了在提交表单时进行正确的数据绑定:

<select data-val="true" data-val-number="The field SelectedValue must be a number." id="ParentDropDown_SelectedValue" name="ParentDropDown.SelectedValue">

如何将这些属性添加到我自己的模板中?

4

1 回答 1

30

没错,这些属性(特别是 name 属性)对于模型绑定至关重要。

假设您要创建一个自定义助手,例如

public static MvcHtmlString CustomHelperFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)

首先,您可以使用var fieldName = ExpressionHelper.GetExpressionText(expression);来获取字段名称。

然后使用var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);以获取全名,照顾嵌套视图。

最后,您可以使用 将其转换为 id 属性var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);

所以一个创建文本框的简单自定义助手可以写成:

public static MvcHtmlString CustomHelperFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{            
    var fieldName = ExpressionHelper.GetExpressionText(expression);
    var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
    var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);

    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    var value = metadata.Model;

    TagBuilder tag = new TagBuilder("input");
    tag.Attributes.Add("name", fullBindingName);
    tag.Attributes.Add("id", fieldId);
    tag.Attributes.Add("type", "text");
    tag.Attributes.Add("value", value == null ? "" : value.ToString());

    var validationAttributes = html.GetUnobtrusiveValidationAttributes(fullBindingName, metadata);
    foreach (var key in validationAttributes.Keys)
    {
        tag.Attributes.Add(key, validationAttributes[key].ToString());
    }

    return new MvcHtmlString(tag.ToString(TagRenderMode.SelfClosing));
}

您可以在如下视图中使用它:

@Html.CustomHelperFor(model => model.ParentDropDown.SelectedValue)

它将产生以下html:

<input id="ParentDropDown_SelectedValue" name="ParentDropDown.SelectedValue" type="text" value="4">

希望能帮助到你!

于 2013-08-10T12:45:05.443 回答