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

发布于 2024-09-10 11:47:09 字数 1391 浏览 0 评论 0原文

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

PropertyFeatureID: 2
Description: "Swimming Pool"

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

<%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 并渲染匹配的标签,以便用户可以直观地单击标签并切换复选框 - 这非常有效。

我将复选框的“名称”设置为“功能”,以便所有复选框都以相同的名称呈现,并且在发布表单时,MVC 模型绑定器将它们堆积到一个名为“功能”的集合中。这很好用。

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

单击按钮时,我能够从控制器方法中检索选定的值,因为我已将参数指定为 int[] 功能。

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

我花了几个小时阅读有关类似问题的所有其他线程和文章,并且有很多关于使用 ICollectionIDictionary 来捆绑事物并包含布尔值的讨论对于每个项目,以便它可以保持复选框状态。但我并没有 100% 掌握如何在我自己的个人示例中使用它。我希望保持解决方案非常简单,而不必仅仅为了维护我的复选框状态而编写新类的页面。

最干净、最正确的方法是什么?

I have a class called "PropertyFeature" which simply contains PropertyFeatureID and Description. It's a proper model created through LINQ to SQL mapped to an SQL Server database table. An example instance/row would be:

PropertyFeatureID: 2
Description: "Swimming Pool"

The number of rows (PropertyFeatures) can of course grow and shrink, and so I want to dynamically render a list of checkboxes so that the user can select any of them.
I can dynamically render the Checkboxes easily enough, with something like:

<%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>
<%}%>

I specify the ID for each checkbox and render the matching label so that the user can intuitively click the label and toggle the checkbox - that works great.

I set the CheckBox's "name" to "Features" so all the checkboxes render with the same name, and the MVC Model Binder piles them into a single collection called "Features" when the form is posted. This works nicely.

Once the form is submitted, I use the checked values and store them, so I need the actual integer values so I know which PropertyFeature is selected, not just a pile of Booleans and field names. So ideally, I want it as an array or a collection that's easy to work with.

I am able to retrieve the selected values from within my Controller method when the button is clicked because I have specified the parameter as int[] Features.

But the problem is that it doesn't maintain state. That is, when I click the submit button and the page reloads (with the form again displayed) I want all of the dynamic checkboxes to retain their checked status (or not). All of the other fields that I've created with Html.DropDownList and Html.TextBox all maintain their states successfully no problems at all on the same page in the same form.

I have spent hours reading all of the other threads and articles on similar issues and there is a lot of talk about using ICollection and IDictionary to bundle things up and include a Boolean value for each item so that it can maintain the checkbox state. But I don't 100% grasp how to use that in the context of my own personal example. I would like to keep the solution really simple and not have to code up pages of new classes just to maintain my checkbox state.

What is the cleanest and proper way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜声 2024-09-17 11:47:09

经过多次尝试各种不同的方法后,我让它发挥了作用。

在视图中:

<%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 方法接收一个超级整洁的整数数组,该数组仅包含已选择的整数 - 而不是一堆未选择或包含 false/null/blank/0 等的其他项目。
  • 保留复选框的选中状态当包含表单的页面重新加载时,即保留用户的选择。
  • 没有随机/杂散类型=从默认的 ASP.Net MVC Html.CheckBox 帮助器创建的隐藏输入字段 - 我知道它这样做是有充分理由的,但在这种情况下,我不需要它们,因为我只想知道哪些 ID 已被选择,哪些 ID 位于单个、整洁的 int[] 中。
  • 实现如此简单的事情不需要大量额外的服务器端臃肿类、助手和其他令人愉快的混乱。

我会向任何想要最干净/无膨胀解决方案的动态复选框列表的人推荐这种方法,您需要 ID,并且只想开始做正事!

I got it working after much playing around with the various different approaches.

In the view:

<%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>   <%
   }  %>

In the receiving controller method:

public ActionResult SearchResults(int[] Features)

This method has a number of advantages:

  • Allows labels to be clicked to toggle the corresponding checkboxes (usability).
  • Allows the Controller method to receive a super tidy array of ints, which ONLY contains the ints that have been selected - and not a whole other pile of items which were unselected or containing false/null/blank/0 etc.
  • Retains the checkbox's checked state when the page reloads containing the form, i.e. the user's selection is retained.
  • No random/stray type=hidden input fields created from the default ASP.Net MVC Html.CheckBox helper - I know it does those for a good reason, but in this instance, I don't require them as I only want to know about which IDs have been selected and for those to be in a single, tidy int[].
  • No masses of additional server side bloated classes, helpers and other happy mess required to achieve such a simple thing.

I would recommend this approach for anyone wanting the cleanest / bloat-free solution for a dynamic checkbox list where you need the IDs and you just want to get down to business!

夏花。依旧 2024-09-17 11:47:09

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

比如:

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

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

The problem is that when you are rendering your list of checkboxes, you aren't setting any of them as selected. You will need to set your int[] Features in ViewData, and then in your foreach loop, check to see if the ID of that Feature is in the array in ViewData.

something like:

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

although I didn't test it, so it might not be 100%.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文