创建一个辅助程序以覆盖CheckboxFor

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>'中不包含定义为'CheckBoxFor'的内容,而最佳扩展方法重载'System.Web.Mvc.Html.InputExtensions.CheckBoxFor<TModel>(System.Web.Mvc.HtmlHelper<TModel>, System.Linq.Expressions.Expression<System.Func<TModel,bool>>)'具有一些无效参数

如果我将TProperty更改为bool,则会编译,但我在调用此助手的行上获得运行时错误:

CS0411:无法从使用中推断出方法'CollectionSystem.Helpers.FormHelpers.MyCheckboxFor<TModel,TProperty>(System.Web.Mvc.HtmlHelper<TModel>, System.Linq.Expressions.Expression<System.Func<TModel,bool>>)'的类型参数。尝试明确指定类型参数。

请问有人能够建议我如何包装CheckboxFor函数吗?


也许这会有所帮助:https://dev59.com/A3E85IYBdhLWcg3wmExW#56256649 - VDWWD
2个回答

10

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

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

Views\Shared\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>

或者对于您的复选框场景,例如:

Views\Shared\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,将使用正确的编辑器模板,无需开发人员记住使用任何自定义帮助程序。

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


谢谢Chris。我正在阅读你的博客,并在这一部分发现了一个错别字:“听起来很简单。问题何在?”,第一段,第三行,“…为这些视图建立模型…”。 - Celdor
@Chris Pratt 用EditorTemplates同时使用复选框和单选按钮怎么样? - T-moty
通常情况下,bool 类型不会使用收音机,除非您确实希望在 true 和 false 值之间使用收音机。但是,如果您想要能够处理相同类型(在本例中为 bool)的两种值,则需要某种区分方式。这可以通过多种方式完成。您可以在属性上使用类似 [UIHint("Radio")] 的东西来指定应使用 Radio.cshtml 编辑器模板。或者,您可以将某些值传递到模板的 ViewData 中,并在其上进行分支:Html.EditorFor(m => m.SomeBool, new { useRadios = true }),然后在 ViewData["useRadios"] 上进行分支。 - Chris Pratt

4
你需要的帮助助手就像这样:
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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接