维护ASP.NET MVC中动态的复选框列表的状态

时间:2010-07-20 15:16:46

标签: asp.net-mvc binding checkbox viewmodel state

我有一个名为“PropertyFeature”的类,它只包含PropertyFeatureID和Description。它是通过映射到SQL Server数据库表的LINQ to SQL创建的正确模型。示例实例/行将是:

PropertyFeatureID: 2
Description: "Swimming Pool"

行数(PropertyFeatures)当然可以增长和缩小,因此我想动态呈现一个复选框列表,以便用户可以选择其中任何一个。 我可以很容易地动态渲染Checkbox,例如:

<%foreach (var Feature in (ViewData["Features"] as IEnumerable<MySolution.Models.PropertyFeature>)) { %>
<%=Html.CheckBox("Features", new { @id = Feature.PropertyFeatureID, @value = Feature.PropertyFeatureID })%><label for="Feature<%=Feature.PropertyFeatureID%>"><%=Feature.Description%></label>
<%}%>

我指定每个复选框的ID并呈现匹配的标签,以便用户可以直观地点击标签并切换复选框 - 这非常有效。

我设置了CheckBox的“名”,以“特色”,让所有的复选框使具有相同的名称,以及MVC模型绑定桩他们到时调用的形式发布“功能”单个集合。这很好用。

一旦提交表单,我用的是检查的值,并将其储存,所以我需要实际的整数值,所以我知道这PropertyFeature选择,而不仅仅是一堆布尔和字段名。理想情况下,我希望它可以作为一个易于使用的数组或集合。

单击按钮时,我可以从Controller方法中检索所选值,因为我已将参数指定为int [] Features。

但问题是它不维护状态。也就是说,当我单击提交按钮并重新加载页面(再次显示该表单)时,我希望所有动态复选框都保留其已检查状态(或不保留)。我使用Html.DropDownListHtml.TextBox创建的所有其他字段都在同一页面上以相同的形式成功维护其状态。

我花了几个小时阅读关于类似问题的所有其他主题和文章,并且有很多关于使用ICollectionIDictionary进行捆绑的讨论,并为每个项目包含一个布尔值这样它就可以保持复选框状态。但我并没有100%掌握如何在我个人的例子中使用它。我想保持解决方案非常简单,不必为了保持我的复选框状态而编写新类的页面。

最干净,最恰当的方法是什么?

2 个答案:

答案 0 :(得分:15)

在经历了各种不同的方法后,我开始工作了。

在视图中:

<%string[] PostFeatures = Request.Form.GetValues("Features");%>
<% foreach (var Feature in (ViewData["AllPropertyFeatures"] as 
                             IEnumerable<MySolution.Models.PropertyFeature>)) 
   { %>
    <input type="checkbox" name="Features"
        id="Feature<%=Feature.PropertyFeatureID.ToString()%>" 
        value="<%=Feature.PropertyFeatureID%>" 
        <%if(PostFeatures!=null) 
          {
             if(PostFeatures.Contains(Feature.PropertyFeatureID.ToString()))
             { 
                Response.Write("checked=\"checked\""); 
             }
          }
        %> />
    <label for="Feature<%=Feature.PropertyFeatureID%>">
          <%=Feature.Description%></label>   <%
   }  %>

在接收控制器方法中:

public ActionResult SearchResults(int[] Features)

这种方法有许多优点:

  • 允许点击标签以切换相应的复选框(可用性)。
  • 允许Controller方法接收一个超级整齐的int数组,它只包含已经选择的整数 - 而不是一整堆未被选中或包含false / null / blank / 0等的项目。
  • 当页面重新加载包含表单时保留复选框的选中状态,即保留用户的选择。
  • 没有随机/流浪类型=从默认的ASP.Net MVC Html.CheckBox帮助器创建的隐藏输入字段 - 我知道这样做有充分理由,但在这个例子中,我不需要它们,因为我只想要了解哪些ID已被选中,以及哪些ID在一个整齐的int []。
  • 没有大量额外的服务器端臃肿的类,助手和其他快乐的混乱所需要实现这么简单的事情。

对于想要动态复选框列表的最干净/无膨胀解决方案的人,我会推荐这种方法,您需要这些ID,而您只想开展业务!

答案 1 :(得分:0)

问题是,当您渲染复选框列表时,您没有将其中任何一个设置为已选中。您需要在ViewData中设置int[] Features,然后在foreach循环中,检查该功能的ID是否在ViewData的数组中。

类似的东西:

<%=Html.CheckBox("Features", 
    ((int[])ViewData["SelectedFeatures"]).Contains(Feature.PropertyFeatureID),
    new { @id = Feature.PropertyFeatureID, @value = Feature.PropertyFeatureID })%

虽然我没有测试它,但它可能不是100%。