asp.net-mvc 在 ListBoxFor 中选择值的挑战

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3194143/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:22:45  来源:igfitidea点击:

Challenges with selecting values in ListBoxFor

asp.net-mvcasp.net-mvc-2

提问by JohnMc0831

Working on my first ASP.Net MVC2 web app recently, I came across some issues when I needed to select multiple values in a list box. I worked around it with some jQuery, but went ahead and put together some very simple code to demonstrate. I'm using EF for the model, with two entities - Customers and HelpDeskCalls:

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

Controller:

控制器:

 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);
    }

View:

看法:

<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>

For this sample, I'm just selecting HelpDeskCall.IDs which are even. I'm trying two different syntaxes for ListBoxFor: One uses an IEnumerable of values for selections, one using an IEnumerable of SelectListItems. By default, when I run this code, no selections are made to either ListBoxFor, but the non-strongly typed ListBox selects correctly.

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

I read this poston ASP.Net and this threadon SO, but no joy. In fact, if I add the override ToString() to my HelpDeskCall class (as suggested in the ASP.net thread) all values are selected, which isn't right either.

我读这篇文章的ASP.Net和这个线程的SO,但没有喜悦。事实上,如果我将覆盖 ToString() 添加到我的 HelpDeskCall 类(如 ASP.net 线程中所建议的),则所有值都会被选中,这也不正确。

If someone could shed some light on how this should work (and what I'm missing or doing wrong), this then neophyte would be very grateful.

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

回答by Darin Dimitrov

Here's an example illustrating the strongly typed version:

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

Model:

模型:

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

Controller:

控制器:

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);
    }
}

View:

看法:

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

回答by kkara

I don't know if this behaviour has changed in the RTM of MVC3 that I'm using, but it seems that selection and binding now works out of the box. The only catch is that the model should contain a property with the IDs, like that :

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

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

Then the following in the view would work fine, both pre-selecting the correct values and binding correctly during post:

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

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

回答by Daniel Steigerwald

I have found better workaround. Usual way to preselect select list:

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

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

Doesn't work.., never ever any option is selected, until:

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

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);
}

Selected Roles has to be stored in ViewData, to workaround nasty bug.

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

回答by Jamie

Another option is to take advantage of nameof, you could do something like this;

另一种选择是利用nameof,你可以做这样的事情;

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