我知道其他人已经问过这个问题了,但我对此完全感到困惑:
这将显示未选择任何值的下拉列表:
<%= Html.DropDownList("items", new MultiSelectList(Model.AvailableItems,
"id", "name", Model.items), new { multiple = "multiple" })%>
Run Code Online (Sandbox Code Playgroud)
这将显示下拉列表,其中包含我正在传入的值(Model.items),就像我期望的那样:
<%= Html.DropDownList("somethingelse", new MultiSelectList(Model.AvailableItems,
"id", "name", Model.items), new { multiple = "multiple" })%>
Run Code Online (Sandbox Code Playgroud)
但问题是,当我发布POST时,此项目现在被命名为"somethingelse".我知道我可以解决这个问题但是会发生什么?
Dar*_*rov 52
您的问题提供的上下文太少,但我会尝试展示一个完整的工作示例:
模型:
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
}
public class MyModel
{
public IEnumerable<int> SelectedItemIds { get; set; }
public IEnumerable<Item> AvailableItems {
get
{
return new[]
{
new Item { Id = 1, Name = "Item 1" },
new Item { Id = 2, Name = "Item 2" },
new Item { Id = 3, Name = "Item 3" },
};
}
}
}
Run Code Online (Sandbox Code Playgroud)
控制器:
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyModel
{
SelectedItemIds = new[] { 2, 3 }
};
return View(model);
}
[HttpPost]
public ActionResult Index(IEnumerable<int> selectedItemIds)
{
var model = new MyModel
{
// Important: Don't ever try to modify the selectedItemIds here
// The Html helper will completely ignore it and use
// the POSTed values
SelectedItemIds = selectedItemIds
};
return View(model);
}
}
Run Code Online (Sandbox Code Playgroud)
视图:
<% using (Html.BeginForm()) { %>
<%= Html.ListBoxFor(x => x.SelectedItemIds,
new MultiSelectList(Model.AvailableItems, "Id", "Name")) %>
<input type="submit" value="GO" />
<% } %>
Run Code Online (Sandbox Code Playgroud)
请注意,Html.ListBoxFor如果要生成多重选择,则更适合.显然AvailableItems应该从存储库中获取属性.
Jer*_*ero 21
您遇到的问题是使用Model.Items作为参数.代码
<%= Html.DropDownList("items", new MultiSelectList(Model.AvailableItems,
"id", "name", Model.items), new { multiple = "multiple" })%>
Run Code Online (Sandbox Code Playgroud)
实际上并没有像你期望的那样工作.这是有效的,因为下拉列表的名称是"items".那是因为有一个名为"items"的表单参数发布回您的操作.该参数存储在动作的ViewState中(不要与ViewData混淆).Html.DropdownList()看到有一个ViewState参数名称与您命名的下拉列表相同,并使用该ViewState参数来计算选定的值.它完全忽略了您传入的Model.items.
如果有人能够解释无法覆盖默认行为的逻辑,那么我很乐意听到它.
那么,那是你的第一个问题.要解决这个问题,您只需将下拉列表重命名为其他内容 - 就像您在第二个示例中所做的那样.现在你的第二个问题发挥作用:所选项目的列表必须是简单对象的集合(我认为它实际上需要是一个IEnumerable,但我不是100%肯定).
DropDownList()方法将尝试将这些选定的值与AvailableItems集合中的Value进行匹配.如果它不能这样做,它将尝试匹配文本.
所以,试试看它是否有效
<%= Html.DropDownList("somethingelse", new MultiSelectList(Model.AvailableItems,
"id", "name", Model.items.Select(c=> c.name)), new { multiple = "multiple" })%>
Run Code Online (Sandbox Code Playgroud)
祝好运
我有同样的问题,我使用自己的扩展方法来生成HTML并解决了问题
public static MvcHtmlString ListBoxMultiSelectFor<TModel, TProperty>(
this HtmlHelper<TModel> helper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> selectList,
object htmlAttributes)
{
return ListBoxMultiSelectFor(helper, expression, selectList, new RouteValueDictionary(htmlAttributes));
}
public static MvcHtmlString ListBoxMultiSelectFor<TModel, TProperty>(
this HtmlHelper<TModel> helper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> selectList,
IDictionary<string, object> htmlAttributes)
{
string name = ExpressionHelper.GetExpressionText(expression);
TagBuilder selectTag = new TagBuilder("select");
selectTag.MergeAttributes(htmlAttributes);
selectTag.MergeAttribute("id", name, true);
selectTag.MergeAttribute("name", name, true);
foreach (SelectListItem item in selectList)
{
TagBuilder optionTag = new TagBuilder("option");
optionTag.MergeAttribute("value", item.Value);
if (item.Selected) optionTag.MergeAttribute("selected", "selected");
optionTag.InnerHtml = item.Text;
selectTag.InnerHtml += optionTag.ToString();
}
return new MvcHtmlString(selectTag.ToString());
}
Run Code Online (Sandbox Code Playgroud)
实际上,如果您查看 MVC 源代码,则默认情况下此行为已烘焙到 DropDownListFor 中(搜索 allowMultiple: false)。解决方案是改用 ListBoxFor(您将在 MVC 源代码中看到,allowMultiple: true),这在 HTML 方面很有意义,两者都呈现为
<select ...>
<option ...>
<option ...>
...
</select>
Run Code Online (Sandbox Code Playgroud)
您不必按照上面的答案中的建议在模型上使用不同的属性,我通过简单地切换到 ListBoxFor 来实现这一点(CSS 从那里获取它):
@Html.ListBoxFor(model => model.SelectedCategories,
new MultiSelectList(Model.Categories, Model.SelectedCategories),
new { multiple = "multiple" })
Run Code Online (Sandbox Code Playgroud)
即使使用 POST 并在出错时重新显示视图,它也能像魅力一样工作。
| 归档时间: |
|
| 查看次数: |
48237 次 |
| 最近记录: |