MVC-4 不支持选项组,您需要升级到 MVC-5 才能使用开箱即用的功能。如果您进行升级,请参阅使用 OptGroup 组构建选择列表以获取使用SelectList
构造函数的示例,并通过生成IEnumerable<SelectListItem>
在不升级的情况下,您可以将代表您的组及其选项的模型传递给视图,并使用一些 javascript/jquery 来生成元素。首先创建一些额外的视图模型
public class OptionGroupVM
{
public string GroupName { get; set; }
public IEnumerable<OptionVM> Options { get; set; }
}
public class OptionVM
{
public string Value { get; set; }
public string Text { get; set; }
public bool IsSelected { get; set; } // Only applicable if your not binding to a model property
}
然后修改您的主视图模型以包含以下内容
public class SearchControlViewModel
{
....
public IEnumerable<int> SelectedClasses { get; set; }
public IEnumerable<OptionGroupVM> ClassOptions { get; set; }
}
请注意,您当前的模型和使用ListBoxFor()
不正确,因为
您不能将 a 绑定<select multiple>
到您的属性所在的复杂对象的集合Classes
- 模型需要是值类型的集合,并且
您不能对绑定到的属性使用相同的名称,如果我SelectList
将viewBag 名称指定为与 @Html.DropDownListFor 中的模型属性名称相同,是否会发生冲突以获取更多详细信息
在控制器中
var data = repClass.GetClassesByYear(23);
var groupedOptions = data.GroupBy(x => x.grade).Select(x => new OptionGroupVM()
{
GroupName = x.Key.ToString(),
Options = x.Select(y => new OptionVM()
{
Value = y.classId.ToString(),
Text = y.classcame,
})
});
SearchControlViewModel model = new SearchControlViewModel()
{
....
SelectedClasses = ...., // the values of the options that will be pre-selected
ClassOptions = groupedOptions
};
return View(model);
并在视图中使用
@Html.ListBoxFor(m => SelectedClasses, Enumerable.Empty<SelectListItem>(), new { id = "classList" })
最初将生成<select>
没有任何选项的。然后使用以下脚本生成选项
<script type="text/javascript">
// Get data
var listBox = $('#classList');
var selected = @Html.Raw(Json.Encode(Model.SelectedClasses));
var groups = @Html.Raw(Json.Encode(Model.ClassOptions));
// Generate options
createGroupedOptions(listBox, selected, groups);
// Attach plug-in
listBox.multiselect({ enableClickableOptGroups: true });
// This function could be in an external js file
function createGroupedOptions(element, selected, groups) {
for (var i = 0; i < groups.length; i++) {
var group = groups[i];
var groupElement = $('<optgroup></optgroup>').attr('label', group.GroupName);
for(var j = 0; j < group.Options.length; j++) {
var option = group.Options[j];
var optionElement = $('<option></option>').val(option.Value).text(option.Text);
if (selected) {
if (selected.toString().indexOf(option.Value) >= 0) {
optionElement.attr('selected', 'selected')
}
} else {
if (option.IsSelected) {
optionElement.attr('selected', 'selected')
}
}
$(groupElement).append(optionElement);
}
$(element).append(groupElement);
}
}
</script>