【问题标题】:Challenges with selecting values in ListBoxFor在 ListBoxFor 中选择值的挑战
【发布时间】:2010-07-07 11:15:22
【问题描述】:

最近在开发我的第一个 ASP.Net MVC2 Web 应用程序时,当我需要在列表框中选择多个值时遇到了一些问题。我用一些 jQuery 解决了这个问题,但继续编写了一些非常简单的代码来演示。我在模型中使用 EF,有两个实体 - 客户和 HelpDeskCalls:

控制器:

 public ActionResult Edit(int id)
    {
        Customer currCustomer = ctx.Customers.Include("HelpDeskCalls").Where(c => c.ID == id).FirstOrDefault();
        List<HelpDeskCall> currCustCalls = (ctx.HelpDeskCalls.Where(h => h.CustomerID == id)).ToList();
        List<SelectListItem> currSelectItems = new List<SelectListItem>();
        List<String> selectedValues = new List<string>();
        foreach (HelpDeskCall currCall in currCustCalls)
        {
            bool isSelected = (currCall.ID % 2 == 0) ? true : false;
            //Just select the IDs which are even numbers...
            currSelectItems.Add(new SelectListItem() { Selected = isSelected, Text = currCall.CallTitle, Value = currCall.ID.ToString() });
            //add the selected values into a separate list as well...
            if (isSelected)
            {
                selectedValues.Add(currCall.ID.ToString());
            }
        }
        ViewData["currCalls"] = (IEnumerable<SelectListItem>) currSelectItems;
        ViewData["currSelected"] = (IEnumerable<String>) selectedValues;
        return View("Edit", currCustomer);
    }

查看:

<div class="editor-field">
    <%: Html.ListBoxFor(model => model.HelpDeskCalls, new MultiSelectList(Model.HelpDeskCalls, "ID", "CallTitle", (IEnumerable) ViewData["currSelected"]), new { size = "12" })%>       
    <%: Html.ListBoxFor(model => model.HelpDeskCalls, ViewData["currCalls"] as IEnumerable<SelectListItem>, new { size = "12"}) %>
    <%: Html.ListBox("Model.HelpDeskCalls", new MultiSelectList(Model.HelpDeskCalls, "ID", "CallTitle", (IEnumerable)ViewData["currSelected"]), new { size = "12"}) %>      
    <%: Html.ValidationMessageFor(model => model.HelpDeskCalls) %>
</div>

对于这个示例,我只是选择了偶数的 HelpDeskCall.ID。我正在为 ListBoxFor 尝试两种不同的语法:一种使用 IEnumerable 值进行选择,一种使用 IEnumerable 的 SelectListItems。默认情况下,当我运行此代码时,不会对任何一个 ListBoxFor 进行选择,但非强类型 ListBox 会正确选择。

我在 ASP.Net 上阅读了 this post,在 SO 上阅读了 this thread,但并不高兴。事实上,如果我将覆盖 ToString() 添加到我的 HelpDeskCall 类(如 ASP.net 线程中所建议的那样),所有值都会被选中,这也不正确。

如果有人能阐明这应该如何工作(以及我错过了什么或做错了什么),那么新手将非常感激。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-2


    【解决方案1】:

    这是一个说明强类型版本的示例:

    型号:

    public class MyViewModel
    {
        public int[] SelectedItemIds { get; set; }
        public MultiSelectList Items { get; set; }
    }
    

    控制器:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            // Preselect items with id 1 and 3
            var selectedItemIds = new[] { 1, 3 };
    
            var model = new MyViewModel
            {
                Items = new MultiSelectList(
                    new[] 
                    {
                        // TODO: Fetch from your repository
                        new { Id = 1, Name = "item 1" },
                        new { Id = 2, Name = "item 2" },
                        new { Id = 3, Name = "item 3" },
                    }, 
                    "Id", 
                    "Name", 
                    selectedItemIds
                )
            };
    
            return View(model);
        }
    }
    

    查看:

    <%: Html.ListBoxFor(x => x.SelectedItemIds, Model.Items) %>
    

    【讨论】:

    • 太棒了!我花了一段时间试图让这个工作。这也对我有用。非常感谢!点赞。
    • 泰!这帮了我很多忙。
    • 你就是男人! :D 感谢您在整个 StackOverflow 中帮助提供如此好的和干净的代码示例。上帝保佑你的生活!
    • @Darin:如果我使用MyViewModel 作为发布操作的参数,SelectedItemIds 将由模型绑定器填充,其中包含已在列表框中选择的项目的所有 Id页面?
    • 请注意,如果您需要选择多个值,请确保您使用 MultiSelectList 而不是 SelectList 实例化 MultiSelectList 属性,我费了很多力气才明白为什么我总是只选择一个项目。跨度>
    【解决方案2】:

    我不知道这种行为是否在我正在使用的 MVC3 的 RTM 中发生了变化,但似乎选择和绑定现在可以开箱即用。唯一的问题是模型应该包含一个带有 ID 的属性,就像这样:

    public class MyViewModel {
        public int[] ItemIDs { get; set; }
    }
    

    然后视图中的以下内容可以正常工作,既可以预先选择正确的值,又可以在发布期间正确绑定:

    @Html.ListBoxFor(model => model.ItemIDs, (IEnumerable<SelectListItem>)(new[] { 
                                    new SelectListItem() { Value = "1", Text = "1" }, 
                                    new SelectListItem() { Value = "2", Text = "2" } 
                                 }))
    

    【讨论】:

    • 一个小修正。尽管上述方法有效,但似乎存在一些可能导致问题的小错误。似乎当 ViewBag 包含一个名为“X”的属性并且模型的属性也被命名为“X”时,ListBox 的自动选择不起作用......奇怪的事情......
    • 那条评论真的救了我!
    • 仍然在 2016 年,这个 cmets 正在帮助我 - 我有一个与绑定模型属性同名的 ViewBag 属性,因此选定的项目填充不起作用。
    【解决方案3】:

    我找到了更好的解决方法。预选选择列表的常用方法:

    @Html.ListBoxFor(
        model => model.Roles, 
        new MultiSelectList(db.Roles, "Id", "Name")
    )
    @Html.ValidationMessageFor(model => model.Roles)    
    

    不起作用..,永远不会选择任何选项,直到:

    public ActionResult Edit(int id)
    {
        var user = db.Users.Find(id);
        // this is workaround for http://aspnet.codeplex.com/workitem/4932?ProjectName=aspnet
        ViewData["Roles"] = user.Roles.Select(r => r.Id);
        return View(user);
    }
    

    选定的角色必须存储在 ViewData 中,以解决讨厌的错误。

    【讨论】:

    • 可能很明显(但仍然很高兴知道):如果您使用 MVC3 样式的 ViewBag.Roles,这也有效。
    【解决方案4】:

    另一个选择是利用nameof,你可以这样做;

    Html.ListBox(nameof(MainProjectViewModel.Projects), Model.Projects)
    

    【讨论】:

      猜你喜欢
      • 2017-06-26
      • 1970-01-01
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-13
      • 2013-12-21
      相关资源
      最近更新 更多