繁体   English   中英

如何创建复选框列表?

[英]How to create a checkbox list?

我知道有很多CheckBoxListFor helper方法的自定义实现,以填补MVC框架中缺少的功能。 但是我还没有准备好使用它们。 我有兴趣仅使用MVC 4或5提供的功能创建复选框列表。 因此,我创建了这个模型类:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace MvcApplication1.Models
{
    public class FruitViewModel
    {
        public int[] SelectedFruits { get; set; }
        public IList Fruits
        {
            get
            {
                return new List{
                new Fruit{Id=1, Name="Apple", Selected = false}, 
                new Fruit{Id=2, Name="Banana", Selected = false}, 
                new Fruit{Id=3, Name="Cherry", Selected = false}, 
                new Fruit{Id=4, Name="Durian", Selected = false}, 
                new Fruit{Id=5, Name="Elderweiss Grape", Selected = false}
            };
            }
        }
    }

    public class Fruit
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool Selected { get; set; }
    }
}

这是控制器类:

using MvcApplication1.Models;
using System.Web.Mvc;

namespace MvcApplication1.Controllers
{
    public class FruitController : Controller
    {
        public ActionResult Index()
        {
            FruitViewModel model = new FruitViewModel();
            return View(model);
        }

        [HttpPost]
        public ActionResult Index(FruitViewModel model)
        {
            if (ModelState.IsValid)
            {   
            }

            return View(model);
        }
    }
}

这是剃刀视图:

@model MvcApplication1.Models.FruitViewModel

@{
    ViewBag.Title = "Index";
}

<h2>Select your favorite fruits</h2>

@using (Html.BeginForm("Index", "Fruit"))
{
    <p>Using Html helper method:</p>
    for (int i = 0; i < Model.Fruits.Count; i++)
    {

        @Html.CheckBoxFor(m => m.Fruits[i].Selected) @Model.Fruits[i].Name<br />
    }

    <p>Plain html without html helper</p>

      for (int i = 0; i < Model.Fruits.Count; i++)
    {
          <input type="checkbox" name="SelectedFruits" value="@Model.Fruits[i].Id" checked="@Model.Fruits[i].Selected" />
 @Model.Fruits[i].Name<br />
    }

    <input type="submit" name="submit" value="Submit" />
}

这是我遇到的问题:

  1. 从屏幕截图中可以看到,纯HTML版本将正确地用我选择的水果的ID填充SelectedFruits集合。 但是,当页面在发回后刷新时,所选复选框的状态将重置为未选中。

  2. 使用Html帮助程序CheckBoxFor的版本不会用我选择的水果的ID填充我的SelectedFruits集合,尽管它似乎可以保持发回完成后选中的复选框状态。

因此,无论哪种情况,都存在很大的问题。

设置复选框列表的正确方法是什么,这样我就可以正确填充SelectedFruits集合,并在表单发布完成后维护复选框的状态(在页面上添加其他内容以及验证失败时很重要)。 在此处输入图片说明

我建议您可以使用以下解决方案,

控制器更改[仅使用Get方法设置用于显示视图的数据]

public ActionResult Index()
{
    FruitViewModel model = new FruitViewModel();
    model.Fruits = new List<Fruit>
        {
        new Fruit{Id=1, Name="Apple", Selected = false}, 
        new Fruit{Id=2, Name="Banana", Selected = false}, 
        new Fruit{Id=3, Name="Cherry", Selected = false}, 
        new Fruit{Id=4, Name="Durian", Selected = false}, 
        new Fruit{Id=5, Name="Elderweiss Grape", Selected = false}
    };
    return View(model);
}

FruitModel更改后,我们将根据用户选择的水果将属性设置为动态填充。

public int[] SelectedFruits
{
    get
    {
        return Fruits != null && Fruits.Count > 0
        ? Fruits.Where(f => f.Selected == true).Select(f => f.Id).ToArray()
        : new int[0];
    }
    set { }
}

查看页面更改[Index.cshtml]

for (int i = 0; i < Model.Fruits.Count; i++)
{
    @Html.CheckBoxFor(m => m.Fruits[i].Selected) @Model.Fruits[i].Name<br />
    @Html.HiddenFor(m => m.Fruits[i].Id)
    @Html.HiddenFor(m => m.Fruits[i].Name)
}

我在您的代码中发现的问题是,您已在html中将复选框名称属性用作“ SelectedFruits”,以用于手动呈现的复选框。 Html帮助器呈现的标记的名称为“ Fruits [0] .Selected”,等等。

因此,所选水果未正确绑定模型。

请验证当前生成的标记,并在有任何查询的情况下发布您的反馈。

您的问题是,视图模型中的Fruits属性始终创建一个新数组,其中每个水果的Selected属性始终为false。 您可以通过在视图模型中初始化一次数组来解决此问题:

public IList<Fruit> Fruits
{
    get
    {
        if (_fruits == null)
            _fruits = new List<Fruit> {
                new Fruit{Id=1, Name="Apple", Selected = false}, 
                new Fruit{Id=2, Name="Banana", Selected = false}, 
                new Fruit{Id=3, Name="Cherry", Selected = false}, 
                new Fruit{Id=4, Name="Durian", Selected = false}, 
                new Fruit{Id=5, Name="Elderweiss Grape", Selected = false}
            }
        return _fruits;
    };
}
private List<Fruit> _fruits;

解决此问题后,您将必须更新控制器以修复Selected属性:

[HttpPost]
public ActionResult Index(FruitViewModel model)
{
    foreach (int fruitId in model.SelectedFruits)
        model.Fruits[fruitId].Selected = true;

    return View(model);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM