如何让 MultiSelectList 绑定到我的数据模型?

Posted

技术标签:

【中文标题】如何让 MultiSelectList 绑定到我的数据模型?【英文标题】:How can I get my MultiSelectList to bind to my data model? 【发布时间】:2013-11-08 22:28:16 【问题描述】:

我在汽车和许多其他表之间存在多对多关系。在我看来,我希望能够为灯光等项目提供多选列表。我尝试了许多不同的格式,我似乎无法让列表设置选定的项目。我首选的方法是 @html.ListBoxFor(model => model.enitity.relatedentity, Model.SomeSelectListItemList) ,但我似乎无法获取列表以设置视图中的选定项目。

下面是我正在测试的代码 我使用 Asp.net MVC5、C# 和实体框架 6。

这是我的控制器操作

    // GET: Car/Edit/
    [Authorize(Roles = "Ecar")]
    public ActionResult Edit(int id)
    


        CarsEditViewModel carEditViewModel = new CarsEditViewModel();

        carEditViewModel.Cars = unitOfWorkcar.CarRepository.FindIncluding(id);

        IList<Approval> approvalList = unitOfWorkcar.ApprovalRepository.All.ToList();
        IList<Connector> connectorList = unitOfWorkcar.ConnectorRepository.All.ToList();
        IList<InputVoltage> inputVoltagesList = unitOfWorkcar.InputVoltageRepository.All.ToList();



        carEditViewModel.ApprovalList = from c in approvalList select new SelectListItem  Text = c.Name, Value = c.Id.ToString(), Selected = true;

        carEditViewModel.Categories = new MultiSelectList(carEditViewModel.ApprovalList, "Value", "Text", "Selected");


       // ,carEditViewModel.ApprovalList.Select(c => c.Text),carEditViewModel.ApprovalList.Select(c => c.Selected)

        //carEditViewModel.ApprovalList = from c in approvalList select new MultiSelectList( // Selected = (carEditViewModel.Cars.Approvals.Any(app => app.Id == c.Id)) , Text = c.Name, Value = c.Id.ToString() ;
       // carEditViewModel.ConnectorList = from c in connectorList select new SelectListItem  Selected = true,  Text = c.Name, Value = c.Id.ToString() ;
        carEditViewModel.InputVoltageList = from c in inputVoltagesList select new SelectListItem  Text = c.Name, Value = c.Id.ToString() ;



        return View(carEditViewModel);

    

这是我的看法

@model NewBobPortal.ViewModels.CarsEditViewModel

 @using (Html.BeginForm())




   @* @Html.ListBoxFor("SelectedApprovals",model => model., new  @class = "multiselect" )*@
    @*@Html.ListBoxFor(model => model.Cars.Approvals, Model.ApprovalList)
    @Html.ListBoxFor(model => model.Cars.Connectors,Model.ConnectorList, new Multiple = "multiple")
    @Html.ListBoxFor(model => model.ConnectorList, Model.ConnectorList)*@
    @*@Html.ListBox("test",Model.Cars.InputVoltages, Model.InputVoltageList)*@
    @Html.DropDownList("somethingelse", new MultiSelectList(Model.InputVoltageList, "Value", "Text", Model.InputVoltageList.Select(c => c.Value)), new  multiple = "multiple" )
    @Html.DropDownListFor(model => model.Cars.InputVoltages , new MultiSelectList(Model.LensColorList, "Value", "Text", Model.LensColorList.Select(c => c.Value)), new  multiple = "multiple" )


    @Html.ListBoxFor(m => m.Cars.Approvals, Model.Categories)



    <p>
        <input type="submit" value="Save" />
    </p>

这是我的视图模型

using NewBobPortal.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

 namespace NewBobPortal.ViewModels
 
public class CarsEditViewModel

    public Car Cars  get; set; 
    public IEnumerable<SelectListItem> ApprovalList  get; set; 
    public IEnumerable<MultiSelectList> ConnectorList  get; set; 
    public IEnumerable<SelectListItem> InputVoltageList  get; set; 




    public MultiSelectList Categories  get; set; 
    public IEnumerable<Approval> SelectedCategories  get; set; 


【问题讨论】:

【参考方案1】:

为多对多关系发布值的最大问题是模型上没有可绑定的直接字段。这就是视图模型变得非常方便的地方,您已经在使用它,但方式并不完全正确。

首先你需要你的SelectList,它实际上可以只是一个IEnumerable&lt;SelectListItem&gt;。这将包含 所有 可用选项,这很容易。所以在你的视图模型中:

public IEnumerable<SelectListItem> CategoryChoices  get; set; 

在你的行动中:

carEditViewModel.CategoryChoices = approvalList.Select(m => new SelectListItem 
    Text = c.Name,
    Value = c.Id.ToString()
);

请注意,我没有设置 Selected:我们将让 HtmlHelper 处理它。我也没有处理MultiSelectList

现在,您还需要回帖,因为您的值将是 id,我们将使用 List&lt;int&gt;,因此在您的视图模型中:

private List<int> selectedCategories;
public List<int> SelectedCategories

    get
    
        if (selectCategories == null)
        
            selectedCategories = Categories.Select(m => m.Id).ToList();
        
        return selectedCategories;
    
    set  selectedCategories = value; 

这里发生了一些事情。属性的set 方法很简单:当我们返回一个发布的值时,只需将selectedCategories 设置为该值。 get 有点复杂:在这里,我们需要将您的类别对象列表(这里称为Categories,因为我不知道这实际上来自哪里)压缩成这些类别的简单 id 列表。

现在,在你看来:

@Html.ListBoxFor(m => m.SelectedCategories, Model.CategoryChoices)

这就是你所需要的。您正在使用ListBox 控件,因此它已经是一个多选列表。而且,通过将其绑定到所有当前选定的 id 列表,它知道在从 Model.CategoryChoices 获取的 SelectListItems 列表中自动选择哪些项目。

在您的 post 操作中,您需要将这些 id 转换为它们的关联对象:

 var newCategories = repository.Categories.Where(m => carEditViewModel.SelectedCategories.Contains(m.Id));

然后,您可以手动将模型的类别设置到这个新列表中:

car.Categories = newCategories;

【讨论】:

克里斯,这是一个非常棒的答案。我遵循您的操作,但具体是什么使您可以强烈键入@HTML.ListBoxFor 的参数? -谢谢 SelectedCategoriesCategoryChoices 都是视图模型上的属性,然后将其设置为视图的模型。 SelectedCategories 填充了当前关联类别的 id 列表,CategoryChoices 设置为所有类别的列表。 ListBoxFor 然后使用CategoryChoices 创建一个MultiSelectList 并在其值与来自SelectedCategories 的集合匹配的列表项上设置Selected 对于它适用的创建方法为我创建.. 虽然由于某种原因编辑不起作用。是否需要做一些不同的事情?除了设置 .State = EntityState.Modified; @ChrisPratt,我正在研究这个完全相同的问题。在我的视图代码中出现错误:The ViewData item that has the key 'SelectedCategories' is of type 'List1[[System.Int32]]' 但必须是 'IEnumerable' 类型。有什么想法吗? @dmikester1:没有上下文很难说。我建议打开一个单独的问题,您可以在其中发布您的控制器、模型和视图代码。

以上是关于如何让 MultiSelectList 绑定到我的数据模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何遍历 MultiSelectList 发布的值并将每个值插入 ASP.Net MVC 5 中的新数据库行?

如何将 JSON 数据绑定到我的类属性

ANDROID 如何通过适配器将 mutableLiveData 绑定到我的 Recyclerview

如何将另一个组件的输出值绑定到我的组件中的表单控件

我需要弄清楚如何将我的类库中的枚举绑定到我的应用程序中的单选按钮

如何使用 MVC Razor 在编辑器模板中将 Kendo UI Grid 绑定到我的模型集合