如何在asp.net mvc3中显示checkboxlist?

时间:2011-07-29 10:13:24

标签: c# asp.net-mvc entity-framework

我有一个publishers表,我有titles表。我正在使用Entity Framework v4.1。发布者实体具有titles属性,它表示此特定发布者已发布的标题数量(我使用的是pubs数据库)。我想创建一个复选框列表,其中显示所有标题(标题表的所有记录)和该发布者已发布的标题应该被检查。我怎么能这样做?

到目前为止,我只能使用以下代码生成DropDownlist:

<tr>
            <td>
                Titles
            </td>
            <td>
                @Html.DropDownListFor(p => p.titles.ToList()[0], new SelectList(ViewBag.titles, "title_id", "notes"))
            </td>
        </tr>

如何将其转换为复选框列表?

提前致谢:)

修改 阅读Brian's帖后,我取得了一些进展,但是当我提交表单时,没有找到任何值:

我创建了一个部分标题类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace MVCWebApp.Models
{
    public partial class title
    {

        public int Id { get; set; }
        public bool IsChecked { get; set; }
    }
}

这是我的EditorTemplate复选框:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MVCWebApp.Models.title>" %>

<%= Html.HiddenFor(x => x.Id)%>
<%= Html.CheckBoxFor(x => x.IsChecked)%>
<%= Html.DisplayFor(x => x.title1)%>
<br />

从我需要复选框列表的页面我写了这段代码:

 <td>
                @Html.EditorFor(p => ViewData["titles"])
            </td>

这是渲染页面的实际(由嵌套循环导致的高度无效)控制器方法:

 public ActionResult Edit(string id)
        {
            using (PubsEntities entities = new PubsEntities())
            {
                publisher pub = entities.publishers.Include("titles").Where(p => p.pub_id == id).First();
                List<title> titles = entities.titles.ToList();
                foreach (var item in pub.titles)
                {
                   title tit = (from titleItem in titles where item.pub_id == titleItem.pub_id select item).First();
                    tit.IsChecked = true;
                }
                ViewData["titles"] = titles;
                return View(pub);
            }
        }

我获得了标题的主列表,并且检查了特定发布者发布的标题。但是,在发布表单时,值都是 null

这是我发布表单的更新方法:

 public ActionResult Update(publisher modifiedPub, List<title> selectedTitle )
        {
            if (!ModelState.IsValid)
                return View("Edit", modifiedPub);

            using (PubsEntities entities = new PubsEntities())
            {

                publisher pub = entities.publishers.Where(p => p.pub_id == modifiedPub.pub_id).First();
                pub.pub_name = modifiedPub.pub_name;
                pub.state = modifiedPub.state;

                entities.SaveChanges();
                return RedirectToAction("Publishers");
            }
        }

这里selectedTitle为null,即使在modifiedPub.titles中,计数为0.有人可以告诉我哪里错了吗?

提前致谢:)

P.S:我们真的必须这么做才能得到复选框吗?

1 个答案:

答案 0 :(得分:1)

以下行是您的问题:

@Html.EditorFor(p => ViewData["titles"])

每次在ASP.NET MVC应用程序中使用ViewData/ViewBag关键字时,都会遇到问题。这样做的正确方法是使用视图模型。在此视图模型中,您将拥有一个属性Titles,它将是您定义的类型的集合。在您看来,您只需:

@Html.EditorFor(p => p.Titles)

这当然意味着您必须修改Edit控制器操作,以便不会将此pub域模型返回到视图,而是使用您的实际真实视图模型。

像这样:

public class TitleViewModel
{
    public int Id { get; set; }
    public bool IsChecked { get; set; }
}

public class PublisherViewModel
{
    public IEnumerable<TitleViewModel> Titles { get; set; }

    ... some other properties of a publisher that you want to work on in your view    
}

和控制器:

public ActionResult Edit(string id)
{
    var publisher = _service.GetPublisher(id);

    var viewModel = new PublisherViewModel
    {
        Titles = publisher.Titles.Select(x => new TitleViewModel
        {
            Id = x.Name,
            IsChecked = true
        })
    };

    return View(model);
}

[HttpPost]
public ActionResult Update(PublisherViewModel model)
{
    if (!ModelState.IsValid)    
    {
        return View(model);
    }

    var publisher = ... map the view model to a domain model
    _service.UpdatePublisher(publisher);

    return RedirectToAction("Publishers");
}