我知道其他人已经提出了这个问题,但我完全对此感到困惑:
这会显示没有选择值的下拉列表:
<%= Html.DropDownList("items", new MultiSelectList(Model.AvailableItems,
"id", "name", Model.items), new { multiple = "multiple" })%>
这会显示下拉列表,其中包含我正在传入的值(Model.items),就像我期望的那样:
<%= Html.DropDownList("somethingelse", new MultiSelectList(Model.AvailableItems,
"id", "name", Model.items), new { multiple = "multiple" })%>
但问题是,当我发布POST时,此项目现在被命名为“somethingelse”。我知道我可以解决这个问题但是会发生什么?
答案 0 :(得分:51)
您的问题中提供的上下文太少,但我会尝试展示一个完整的工作示例:
型号:
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" },
};
}
}
}
控制器:
[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);
}
}
查看:
<% using (Html.BeginForm()) { %>
<%= Html.ListBoxFor(x => x.SelectedItemIds,
new MultiSelectList(Model.AvailableItems, "Id", "Name")) %>
<input type="submit" value="GO" />
<% } %>
请注意,如果要生成多重选择,Html.ListBoxFor
会更加适应。显然应该从存储库中获取AvailableItems
属性。
答案 1 :(得分:21)
您遇到的问题是使用Model.Items作为参数。代码
<%= Html.DropDownList("items", new MultiSelectList(Model.AvailableItems,
"id", "name", Model.items), new { multiple = "multiple" })%>
实际上并没有像您期望的那样工作。这是有效的,因为下拉列表的名称是“items”。那是因为有一个名为“items”的表单参数发布回您的操作。该参数存储在动作的ViewState中(不要与ViewData混淆)。 Html.DropdownList()看到有一个ViewState参数名称与您命名的下拉列表相同,并使用该ViewState参数来计算选定的值。 它完全忽略了您传入的Model.items。
如果有人能够解释无法覆盖默认行为的逻辑,那么我很乐意听到它。
所以,那是你的第一个问题。要解决这个问题,您只需将下拉列表重命名为其他内容 - 就像您在第二个示例中所做的那样。现在你的第二个问题开始了:所选项目的列表必须是简单对象的集合(我认为它实际上需要是IEnumerable但我不是100%肯定)。
DropDownList()方法将尝试将这些选定值与AvailableItems
集合中的值进行匹配。如果它不能这样做,它将尝试匹配文本。
所以,试试看它是否有效
<%= Html.DropDownList("somethingelse", new MultiSelectList(Model.AvailableItems,
"id", "name", Model.items.Select(c=> c.name)), new { multiple = "multiple" })%>
祝你好运
答案 2 :(得分:5)
我有同样的问题,我使用自己的扩展方法来生成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());
}
答案 3 :(得分:3)
实际上,如果你看一下MVC源代码,默认情况下这个行为会被挂到DropDownListFor中(搜索allowMultiple:false)。解决方案是使用ListBoxFor(您将在MVC源代码中看到,allowMultiple:true),这在HTML方面很有意义,两者都呈现为
<select ...>
<option ...>
<option ...>
...
</select>
你不必像上面的答案所建议的那样在模型上使用不同的属性,我通过简单地切换到ListBoxFor来实现这一点(CSS从那里获取):
@Html.ListBoxFor(model => model.SelectedCategories,
new MultiSelectList(Model.Categories, Model.SelectedCategories),
new { multiple = "multiple" })
就像魅力一样,即使使用POST并在错误时重新显示视图。
答案 4 :(得分:1)
当使用ListBoxFor
和MultiSelectList
作为ViewBag
属性时,我遇到了类似的问题。 @ jero的answer帮助我弄清楚,如果ViewBag字段和模型字段之间存在命名冲突,则所选值无法正确显示。
如果我执行了以下操作,则这些项目不会显示为已选中。
//Controller
ViewBag.SelectionIds = new MultiSelectView(possibleValues, "Value", "Name", selectedValues);
//View
@Html.ListBoxFor(model => model.SelectionIds, (MultiSelectList)ViewBag.SelectionIds, new { @class = "form-control" })
如果我将其更改为以下内容,则表示没问题。
//Controller
//Changed ViewBag.SelectionIds to ViewBag.SelectionIdList
ViewBag.SelectionIdList = new MultiSelectView(possibleValues, "Value", "Name", selectedValues);
//View
@Html.ListBoxFor(model => model.SelectionIds, (MultiSelectList)ViewBag.SelectionIdList, new { @class = "form-control" })
答案 5 :(得分:0)
您可以转到&#34;项目&#34;的值用这个
<HttpPost()> _
Function Edit(ByVal crm_cliente As crm_cliente, ByVal form As FormCollection) As ActionResult
If ModelState.IsValid Then
Dim items As String
crm_cliente.usuario_modifico = "ejmorales"
crm_cliente.fecha_modifico = Date.Now
items = form("items")
将使用逗号(,)
分隔所选项目