CheckboxList MVC EditorFor Template PostBack

CheckboxList MVC EditorFor Template PostBack

我继承了一些不完整的代码。开发人员使用模板编辑器来创建他的复选框列表。问题是它没有绑定回模型,这样我就可以将数据返回到服务器端。 任何人都有关于如何使用复选框列表的模板编辑器并将数据发送回绑定到模型的示例? 下面是编辑模板内容。

编辑器模板调用了ServiceTypeViewModel.cshtml

     @model List<ViewModels.ServiceTypeViewModel>
<table>

@{int k = 0; int columns = 2;}

@for (int i = 0; i < (Model.Count / columns + (Model.Count % columns == 0 ? 0 : 1)); i++)
{
    <tr>
    @for(int j = 0; j<columns; j++){
        <td>
            @if (k<Model.Count) { 
                <input name="ProvidedServices[@(k)].Name" id="ProvidedServices__@(k)__Name" type="hidden" value="@Model[k].Name">       
                <input name="ProvidedServices[@(k)].Selected" class="CB" id="ProvidedServices__@(k)__Selected" type="checkbox" value="true">
                <input name="ProvidedServices[@(k)].Selected" type="hidden" value="false">
                <input name="ProvidedServices[@(k)].ServiceTypeClass" id="ProvidedServices__@(k)__ServiceTypeClass" type="hidden" value="@Model[k].ServiceTypeClass">       
                <input name="ProvidedServices[@(k)].ServiceType" id="ProvidedServices__@(k)__ServiceType" type="hidden" value="@Model[k].ServiceType">       
                @Html.DisplayFor(m=>Model[k].Name)
                k++;
            }
        </td>
    }
    </tr>
}
</table>

以下型号

  public class ServiceTypeViewModel
    {
        public string ServiceTypeClass { get; set; }
        public string ServiceType { get; set; }
        public bool Selected { get; set; }
        public string Name { get { return ServiceTypeClass + " " + ServiceType; } }
    }
}

EditorFor 主模型中的模板定义。

[UIHint("ServiceTypeViewModel")]
public List<ServiceTypeViewModel> ProvidedServices { get; set; }

Index.cshtml

    @Html.LabelFor(x => x.ProvidedServices)
    @Html.EditorFor(x => x.ProvidedServices) 

如何让它显示为列表?

我让它像上图一样在模板中呈现,但回发 returns providerservices 为 null。下面的代码呈现了两列复选框。

@model List<ViewModels.ServiceTypeViewModel>
<table>
 @{int k = 0; int columns = 2;}

@for (int i = 0; i < (Model.Count / columns + (Model.Count % columns == 0 ? 0 : 1)); i++)
{
   <tr>
    @for(int j = 0; j<columns; j++){
     <td>
   @if (k<Model.Count) { 
    @Html.HiddenFor(m => m[k].Name);
    @Html.HiddenFor(m => m[k].ServiceTypeClass);
    @Html.HiddenFor(m => m[k].ServiceType);
    @Html.CheckBoxFor(m => m[k].Selected);
    @Html.DisplayFor(m => m[k].Name);
  k++;
      }
        </td>
    }
    </tr>
  }
</table>

ServiceTypeViewModel.cshtml改为

@model ViewModels.ServiceTypeViewModel

<tr>
  <td>
    @Html.HiddenFor(m > m.ServiceTypeClass)
    @Html.HiddenFor(m > m.ServiceType)
    @Html.CheckBoxFor(m > m.Selected)
    @Html.DisplayFor(m => m.Name)
  </td>
</tr>

并确保其位于 /Views/Shared/EditorTemplates 文件夹(或 /Views/yourConrollerName/EditorTemplates 文件夹)

旁注:不清楚你的变量 kcolumns 应该做什么,但这个编辑器模板将为你的每个项目生成正确的 html collection

编辑(基于修改后的问题)

如果您想要 2 列布局,请修改模板以使用 <div> 元素并使用 css 设置样式

@model ViewModels.ServiceTypeViewModel
<div>
  @Html.HiddenFor(m > m.ServiceTypeClass)
  ....
</div>

并在主视图中

<div id="container">
  @Html.EditorFor(x => x.ProvidedServices) 
</div>

和css

#container div {
  width: 50%;
  display: inline-block;
  float: left;
}

这将产生一个 2 列,如 this fiddle

所示

或者,如果您确实想使用 table(这不太合适,因为 table 用于表格数据),那么您不能使用 EditorTempate。相反,您需要在主视图

中使用 for 循环
<table>
  <tr>
    @for(int i = 0; i < Model.ProvidedServices.Count; i++)
    {
      <td>
        @Html.HiddenFor(m => m.ProvidedServices[i].ServiceTypeClass)
        @Html.HiddenFor(m => m.ProvidedServices[i].ServiceType)
        @Html.CheckBoxFor(m => m.ProvidedServices[i].Selected)
        @Html.LabelFor(m => m.ProvidedServices[i].Selected, Model.ProvidedServices[i].Name)
      </td>
      if((i + 1) % 2 == 0)
      {
        @:</tr><tr>
      }
    }
  </tr>
</table>

旁注:包含 属性 Name 的隐藏输入有点毫无意义。它是一个只读的 属性(没有 setter)所以它无论如何都不会被绑定。