【问题标题】:How can I get multiple selections from ASP.NET CheckBoxs如何从 ASP.NET CheckBoxes 中获得多项选择
【发布时间】:2011-02-02 03:10:32
【问题描述】:

这看起来应该很容易 - 但我就是无法让它工作!

我的模型中有一个枚举,我想将其显示为复选框列表。用户可以选择多个复选框,我想将其保存在数据库中。

所以枚举是这样的(大约 20 个未删节的元素):

public enum ReferrerType
{
    [Description("No Data")]
    NoData = 9999,
    [Description("Father or Mother")]
    Parents = 1,
    [Description("Brother or Sister")]
    Sibling = 2,
    [Description("Other")]
    Other = 10
}

其中Description 是UI 上显示的内容,数值是要保存在数据库中的内容。这些数字必须保持原样,因为它们直接进入统计数据包。

然后我定义了一个 Referrer 类:

public class Referrer
{
    public virtual Guid Id { get; private set; }
    public virtual ReferrerType{ get; set; }
}

我意识到这可能是一种奇怪的(反)模式。我仓促地开发它,并在闲暇时忏悔。任何有关改进此模型的建议也将不胜感激!

我的控制器设置了列表:

private static IList<string> GenerateReferrerList()
{
    var values = from ReferrerType e in Enum.GetValues(typeof(ReferrerType))
                 select new { Name = e.ToDescription() };

    return values.Select(x => x.Name).ToList();
}

我在我的视图中这样使用它:

<div class="radio-boolean form-field" id="Referrers">
      <p class="form-field-attribute"> <span class="label">Referred By </span> </p>
      <% for (var i = 0; i < ((IList<string>)ViewData["ReferrerList"]).Count; i++)
      { %>
           <p class="form-field-value">
           <%= Html.CheckBox(string.Format("Referrers[{0}].Type", i) ) %>
           <label for="Referrers"> <%= ((IList<string>)ViewData["ReferrerList"])[i]%></label>
       </p>
</div>

而且它不起作用!我想我错过了一些明显的东西,但我不知道是什么。没有错误 - 只是一个空的数据库表应该是引用者...

一如既往,非常感谢任何帮助!

【问题讨论】:

    标签: c# asp.net asp.net-mvc checkbox


    【解决方案1】:

    让我们花点时间看看我们需要什么。我们需要显示一个包含多个复选框(枚举的每个值一个复选框)和关联标签的表单(该标签应该来自枚举上使用的 Description 属性)。提交此表单时,我们希望获取用户检查过的所有值。

    因此,一旦我们明确定义了我们想要做什么,我们就会引入我们的视图模型:

    public class MyViewModel
    {
        public bool IsChecked { get; set; }
        public ReferrerType ReferrerType { get; set; }
        public string Text { get; set; }
    }
    

    然后我们写一个控制器:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = Enum.GetValues(typeof(ReferrerType)).Cast<ReferrerType>().Select(x => new MyViewModel
            {
                ReferrerType = x,
                Text = x.ToDescription() // I guess that's an extension method you wrote
            });
            return View(model);
        }
    
        [HttpPost]
        public ActionResult Index(IEnumerable<MyViewModel> model)
        {
            ...
        }
    }
    

    最后是一个强类型视图,对应于我们控制器的Index 操作(~/Views/Home/Index.aspx):

    <% using (Html.BeginForm()) { %>
        @Html.EditorForModel()
        <input type="submit" value="OK" />
    <% } %>
    

    最后一部分是对应的编辑器模板(~/Views/Home/EditorTemplates/MyViewModel.ascx):

    <%@ Control 
        Language="C#" 
        Inherits="System.Web.Mvc.ViewUserControl<AppName.Models.MyViewModel>" %>
    <%= Html.CheckBoxFor(x => x.IsChecked) %>
    <%= Html.HiddenFor(x => x.ReferrerType) %>
    <label><%: Model.Text %></label>
    

    现在,当此表单在 POST 索引操作中提交时,您将获得所有枚举的列表,其中包含相应的布尔值,指示用户是否检查过它。

    【讨论】:

    • 谢谢 - 很好的回应,我现在试一试 - 这与当前实现的布局方式完全不同,但我希望能够像你建议的那样调整视图模型结构。
    【解决方案2】:

    OT:不要做多余的动作:

    return (from e in Enum.GetValues(typeof(ReferrerType))
            select e.ToDescription()).ToList();
    

    或者只是

    return Enum.GetValues(typeof(ReferrerType)).Select(e => e.ToDescription()).ToList();
    

    【讨论】:

      猜你喜欢
      • 2015-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多