来自1 List 的MVC Multiple DropDownLists

背景:我的页面上有4个下拉列表,它们都使用一个SelectListItem列表来从中提取数据。 所有这4个下拉列表中的所有4个都将具有相同的元素。 每个下拉列表顶部都有一个空元素。

问题:如果我没有从列表中选择呈现第二个的项目,则当页面加载时,第二个列表会自动选择在第一个列表中选择的项目。 这是因为(我认为)列表有一个SelectListItem ,其中Selected = true ,它只是在第二个列表中使用那个。

有没有办法为多个下拉列表使用一个列表源? 我不想重复这个清单4次,除非我绝对要……

代码

 //this is the list source public IEnumerable PossibleItems { get; set; } //this is the code on my .cshtml page @Html.DropDownListFor(x => x.SelectedItem1, Model.PossibleItems) @Html.DropDownListFor(x => x.SelectedItem2, Model.PossibleItems) @Html.DropDownListFor(x => x.SelectedItem3, Model.PossibleItems) @Html.DropDownListFor(x => x.SelectedItem4, Model.PossibleItems) 

2年前,但对于那些发现这一点的人来说,就像我一直在寻找答案Feussy上面的评论是要走的路。 我会试着解释为什么和我发现的东西。

使用上面的OP示例。 必须满足几个条件才能看到所描述的行为。

  • x.SelectedItem1应该有一个值(比如1)。
  • x.SelectedItem2必须为NULL。 (如果它不是可以为空的类型,只是说一个INT,它将默认为0,你将看不到行为)

@Html.DropDownListFor(x => x.SelectedItem1, Model.PossibleItems)放置一个断点

如果您查看Model.PossibleItems,您将看到预期的列表。 让代码继续下一行。 现在,如果你看一下Model.PossibleItems,你会发现Html.DropDownListFor已经在模型上修改了你的选择列表,而不仅仅是使用它! x.SelectedItem1的选项现在不仅在HTML中有一个’selected’属性,而且在你的模型中也是如此! 这似乎是对Html.DropDownListFor的不良行为,但它确实做到了。

现在当你点击@Html.DropDownListFor(x => x.SelectedItem2, Model.PossibleItems)

  • 如果x.SelectedItem2有一个值,它将设置它,你会没事的但……
  • 如果x.SelectedItem2为null,则第二个@ Html.DropDownListFor似乎只是按原样改变(通过第一个DropDownListFor)选择列表,第二个下拉列表将选择x.SelectedItem1。 (因为选择列表本身已被更改)

Feussy的回答是有效的,因为不是在模型上有一个重复使用的selectList,而是创建单独的selectLists,这些selectLists是从模型上的一些List / IEnumerable生成的,而不是被重用。

因此,故事的寓意是不要重复使用具有可空值的selectList,因为Html.DropDownListFor在更改事物时没有任何问题,并且如果值为NULL,则不会清除任何选定的属性。

希望很清楚。

在列表中,需要为四个下拉列表中的每一个创建不同的SelectList实体,如下所示:

 @Html.DropDownListFor(x => x.SelectedItem1, new SelectList(Model.PossibleItems, "dataValue", "textValue", Model.SelectedItem1)) @Html.DropDownListFor(x => x.SelectedItem2, Model.PossibleItems) new SelectList(Model.PossibleItems, "dataValue", "textValue", Model.SelectedItem2)) @Html.DropDownListFor(x => x.SelectedItem3, Model.PossibleItems) new SelectList(Model.PossibleItems, "dataValue", "textValue", Model.SelectedItem3)) @Html.DropDownListFor(x => x.SelectedItem4, Model.PossibleItems) new SelectList(Model.PossibleItems, "dataValue", "textValue", Model.SelectedItem4)) 

在此示例中,“dataValue”和“textValue”是SelectListItem对象的属性,它们对应于下拉选项的值和文本元素。

您目前拥有的代码是最好的方法,它应该可以正常工作。 SelectListItem确实具有Selected属性,但这通常由SelectList实例设置。 否则,您必须自己手动设置此属性。 由于您使用IEnumerable而不是实例化的SelectList ,因此所有项目都应默认为Selected为false。 只有在Razor渲染DropDownListFor控件时,才会将可枚举变为实际的SelectList并根据模型设置其选定的值。 检查您的其他代码,确保您没有在任何地方手动设置所选状态。

FWIW,您不需要手动添加空项: DropDownListFor控件有一种方法可以将空项添加到列表中。

 @Html.DropDownListFor(x => x.SelectedItem1, Model.PossibleItems, string.Empty) 

不使用List ,而是使用SelectList 。 然后,您可以重用DropDownListFor中的项目DropDownListFor

模型:

 public SelectList PossibleItems { get; set; } 

控制器:

 var items = new List(); model.PossibleItems = new SelectList(items, "Value", "Text"); 

视图:

 @Html.DropDownListFor(m => m.Item1, Model.PossibleItems) @Html.DropDownListFor(m => m.Item2, Model.PossibleItems)