来自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)