创建帮助程序以覆盖CheckboxFor

时间:2014-12-04 20:34:49

标签: c# asp.net-mvc asp.net-mvc-4

我在我正在开始的新项目中使用bootstrap 5,而不是必须在表单字段周围编写所有脚手架,我决定创建一个包装器来自动为我执行此操作。

我对textboxfor,textareafor和dropdownlist使用了以下语法:

public static MvcHtmlString MyTextBoxFor<TModel, TProperty>(
        this HtmlHelper<TModel> helper, 
        Expression<Func<TModel, TProperty>> expression)
    {
        var stringbuilder = new MvcHtmlString("<div class='form-group'>" +
                                                    helper.LabelFor(expression, new {@class = "col-sm-3 control-label"}) +
                                                    "<div class='col-sm-5'>" +
                                                        helper.TextBoxFor(expression, new {@class = "form-control"}) +
                                                    "</div>" +
                                              "</div>");

        return stringbuilder;
    }

然后可以按如下方式调用:

@FormHelpers.MyTextBoxFor(Html, x => x.Name)

但是这似乎不适用于checkboxfor:

Error 1 'System.Web.Mvc.HtmlHelper<TModel>' does not contain a definition for 'CheckBoxFor' and the best extension method overload 'System.Web.Mvc.Html.InputExtensions.CheckBoxFor<TModel>(System.Web.Mvc.HtmlHelper<TModel>, System.Linq.Expressions.Expression<System.Func<TModel,bool>>)' has some invalid arguments

如果我将TProperty更改为bool,它将会编译,但我在调用此帮助程序的行上出现运行时错误:

CS0411: The type arguments for method 'CollectionSystem.Helpers.FormHelpers.MyCheckboxFor<TModel,TProperty>(System.Web.Mvc.HtmlHelper<TModel>, System.Linq.Expressions.Expression<System.Func<TModel,bool>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

有人可以建议如何包装CheckboxFor函数。

2 个答案:

答案 0 :(得分:9)

立即停止并删除项目中的所有代码。

你想要的是编辑器模板。首先,在Views\Shared\EditorTemplates创建一个新文件夹。然后,在该文件夹中,创建以DataType枚举的类型或其中一个成员命名的视图。例如:

<强>视图\共享\ EditorTemplates \ String.cshtml

<div class="form-control">
    @Html.Label("", new { @class = "col-sm-3 control-label" })
    <div class="col-sm-5">
        @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue.ToString(), new { @class = "form-control" })
    </div>
</div>

或者您的复选框方案,例如:

<强>视图\共享\ EditorTemplates \ Boolean.cshtml

@model Boolean?
<div class="form-control">
    <div class="col-offset-sm-3 col-sm-5">
        <div class="checkbox">
            <label>
                @Html.CheckBox("", Model ?? false)
                @ViewData.ModelMetadata.GetDisplayName() 
            </label>
        </div>
    </div>
</div>

用你需要的任何其他东西冲洗并重复。然后在您的视图中,您只需要执行以下操作:

@Html.EditorFor(m => m.TheProperty)

根据属性的类型或它所装饰的DataType,将使用正确的编辑器模板,并且没有开发人员必须记住使用的自定义助手。

我在博客上有更深入的解释:

答案 1 :(得分:3)

你好帮手需要像

一样
public static MvcHtmlString BootstrapCheckBoxFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool>> expression)
{

  TagBuilder innerContainer = new TagBuilder("div");
  innerContainer.AddCssClass("col-sm-5");
  innerContainer.InnerHtml = helper.CheckBoxFor(expression, new {@class = "form-control"}).ToString();

  StringBuilder html = new StringBuilder();
  html.Append(helper.LabelFor(expression, new {@class = "col-sm-3 control-label"}));
  html.Append(innerContainer.ToString());

  TagBuilder outerContainer = new TagBuilder("div");
  outerContainer.AddCssClass("form-group");
  outerContainer.InnerHtml = html.ToString();

  return MvcHtmlString.Create(outerContainer.ToString());

}

注意您可能需要对其进行编辑以包含@Html.ValidationMessageFor()