首页 文章

如何创建复选框列表?

提问于
浏览
1

我知道有很多自定义实现的CheckBoxListFor帮助方法来填补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
} <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
} <input type="submit" name="submit" value="Submit" /> }

以下是我遇到的问题:

  • 普通的HTML版本将正确填充SelectedFruits集合和我选择的水果的ID,正如您从屏幕截图中看到的那样 . 但是,在回发后页面刷新时,所选复选框状态将重置为不检查 .

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

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

设置复选框列表的正确方法是什么,以便我可以正确填充SelectedFruits集合,并在表单发布完成后保持复选框的状态(当我在页面上添加其他内容并且验证失败时很重要) .
enter image description here

2 回答

  • 1

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

    控制器更改[仅限获取方法设置要显示的视图的数据]

    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
    @Html.HiddenFor(m => m.Fruits[i].Id) @Html.HiddenFor(m => m.Fruits[i].Name) }

    我在您的代码中发现的问题是您在html中使用了复选框名称属性作为“SelectedFruits”,用于您手动呈现的复选框 . 而由Html Helper呈现的标记的名称为“Fruits [0] .Selected”等...

    因此,所选择的水果没有正确模型化 .

    如有任何疑问,请核实当前生成的标记并发布您的反馈 .

  • 4

    您的问题是viewmodel中的Fruits属性总是创建一个新数组,其中每个水果的 Selected 属性始终为false . 您可以通过在viewmodel中初始化一次数组来修复它:

    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;
    

    一旦's fixed, you'll必须更新您的控制器以修复 Selected 属性:

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

相关问题