我假设 Html.CheckBoxList 是您的扩展,这是您生成的标记。
根据您显示的内容,需要检查两件事:
- 模型绑定器将寻找一个名为 Header 的对象,该对象具有要绑定的字符串属性 h_dist_cd。您的操作方法看起来像 Header 是根视图模型,而不是模型的子对象。
- 我不知道您如何处理清除复选框的情况。正常的技巧是渲染一个具有相同名称的隐藏字段。
也是一个笨蛋,但您想使用 'label for="..."' 以便他们可以单击文本以选中/取消选中和可访问性。
我发现使用扩展来解决这个问题很容易出错。您可能需要考虑使用子视图模型。它更适合MVC2的EditorFor模板系统。
这是我们系统中的一个示例...
在视图模型中,嵌入一个可重用的子模型......
[AtLeastOneRequired(ErrorMessage = "(required)")]
public MultiSelectModel Cofamilies { get; set; }
您可以使用 SelectListItem 的标准列表对其进行初始化...
MyViewModel(...)
{
List<SelectListItem> initialSelections = ...from controller or domain layer...;
Cofamilies = new MultiSelectModel(initialSelections);
...
MultiSelectModel 子模型。请注意对值的设置器覆盖...
public class MultiSelectModel : ICountable
{
public MultiSelectModel(IEnumerable<SelectListItem> items)
{
Items = new List<SelectListItem>(items);
_value = new List<string>(Items.Count);
}
public int Count { get { return Items.Count(x => x.Selected); } }
public List<SelectListItem> Items { get; private set; }
private void _Select()
{
for (int i = 0; i < Items.Count; i++)
Items[i].Selected = Value[i] != "false";
}
public List<SelectListItem> SelectedItems
{
get { return Items.Where(x => x.Selected).ToList(); }
}
private void _SetSelectedValues(IEnumerable<string> values)
{
foreach (var item in Items)
{
var tmp = item;
item.Selected = values.Any(x => x == tmp.Value);
}
}
public List<string> SelectedValues
{
get { return SelectedItems.Select(x => x.Value).ToList(); }
set { _SetSelectedValues(value); }
}
public List<string> Value
{
get { return _value; }
set { _value = value; _Select(); }
}
private List<string> _value;
}
现在您可以将编辑器模板放在 Views/Shared/MultiSelectModel.ascx...
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<WebUI.Cofamilies.Models.Shared.MultiSelectModel>" %>
<div class="set">
<%=Html.LabelFor(model => model)%>
<ul>
<% for (int i = 0; i < Model.Items.Count; i++)
{
var item = Model.Items[i];
string name = ViewData.ModelMetadata.PropertyName + ".Value[" + i + "]";
string id = ViewData.ModelMetadata.PropertyName + "_Value[" + i + "]";
string selected = item.Selected ? "checked=\"checked\"" : "";
%>
<li>
<input type="checkbox" name="<%= name %>" id="<%= id %>" <%= selected %> value="true" />
<label for="<%= id %>"><%= item.Text %></label>
<input type="hidden" name="<%= name %>" value="false" />
</li>
<% } %>
</ul>
<%= Html.ValidationMessageFor(model => model) %>
这种方法的两个优点:
您不必将项目列表与选择值分开处理。您可以将属性放在单个属性上(例如,AtLeastOneRequired 是我们系统中的自定义属性)
您将模型和视图(编辑器模板)分开。例如,我们有水平和垂直布局的复选框。您还可以将“多选”呈现为两个带有来回按钮的列表框、多选列表框等。