在部分视图中将复选框绑定到列表

时间:2015-06-25 01:10:02

标签: c# asp.net-mvc checkbox model-binding asp.net-mvc-viewmodel

我有CreateViewModel

public class CreateViewModel
{
  public AttributesViewModel AttributesInfo { get; set; }
}

AttributesViewModel被发送到部分视图。

public class AttributesViewModel
{
  public AttributesViewModel()
  {
    ChosenAttributes = new List<int>();
  }

  public List<Attributes> Attributes { get; set; }
  public List<int> ChosenAttributes { get; set; }
}

属性列表在局部视图中输出。每个人都有一个复选框。

foreach (var attribute in Model.Attributes)
{
  <input type="checkbox" name="ChosenAttributes" value="@attribute.ID" /> @Attribute.Name
}

当我发布CreateViewModel时,AttributesInfo.ChosenAttributes总是空的,即使我选中了一些方框。如何正确命名每个复选框以使其与ChosenAttributes列表绑定?

我的解决方案

我采用斯蒂芬·穆克的建议来做双向约束。因此,我创建了一个包含Value,Text和IsChecked的CheckboxInfo类。我为它创建了一个EditorTemplate:

@model Project.CheckboxInfo

@Html.HiddenFor(model => model.Text)
@Html.HiddenFor(model => model.Value)
@Html.CheckBoxFor(model => model.IsChecked)&nbsp;@Model.Text

一个GIANT警告。为了使其正常工作,我必须为AttributesViewModel类创建一个EditorTemplate。没有它,当发布CreateViewModel时,它无法将复选框链接到AttributesInfo。

2 个答案:

答案 0 :(得分:1)

您为复选框name="ChosenAttributes"命名,但CreateViewModel不包含名为ChosenAttributes的属性(只有一个名为AttributesInfo)。您可以使用

进行此项工作
<input type="checkbox" name="AttributesInfo.ChosenAttributes" value="@attribute.ID" /> @Attribute.Name

但正确的方法是使用包含布尔属性(例如)bool IsSelected的正确视图模型,并使用强类型帮助程序绑定到for循环中的属性或使用自定义EditorTemplate以便您的控件名称正确,并且您可以获得双向模型绑定。

答案 1 :(得分:0)

我有类似的情况,但这就是我做到的。解决方案并不完美所以请原谅我是否遗漏了什么,但你应该能够联系。我也试图简化你的解决方案:)

我将Attribute班级名称更改为CustomerAttribute,将其重命名为您喜欢的名称,使用单数名称,而不是复数。在CustomerAttribute课程中添加一个属性,随意调用它,我称之为IsChange

public class CustomerAttribute
{
     public bool IsChange { get; set; }

     // The rest stays the same as what you have it in your Attributes class

     public string Name { get; set; }  // I'm assuming you have a name property
}

删除你的AttributesViewModel课程,你真的不需要它,我喜欢简单。

修改您的CreateViewModel课程,如下所示:

public class CreateViewModel
{
     public CreateViewModel()
     {
          CustomerAttributes = new List<CustomerAttribute>();
     }

     public List<CustomerAttribute> CustomerAttributes { get; set; }
}

你的控制器看起来像这样:

public ActionResult Create()
{
     CreateViewModel model = new CreateViewModel();

     // Populate your customer attributes

     return View(model);
}

您的帖子控制器操作方法如下所示:

[HttpPost]
public ActionResult Create(CreateViewModel model)
{
     // Do whatever you need to do
}

在您看来,您将拥有以下内容:

<table>
     <tbody>

          @for (int i = 0; i < Model.CustomerAttributes.Count(); i++)
          {
               <tr>
                    <td>@Html.DisplayFor(x => x.CustomerAttributes[i].Name)</td>
                    <td>@Html.CheckBoxFor(x => x.CustomerAttributes[i].IsChange)</td>
               </tr>
          }

     <tbody>
</table>

创建示例应用并尝试上面的代码,看看它是否适合您。