MVC List<SelectListItem> 包含为每个项目创建 optgroup 的组
MVC List<SelectListItem> with groups creating optgroup for each item
我遇到一个问题,我正在用 optgroups
创建一个 List<SelectListItem>
,但不是为每组 SelectListItem
创建一个 optgroup
,而是创建一个新的SelectListGroup
每 SelectListItem
。这让我有点困惑,因为我的代码中没有任何重复的 SelectListGroup
。
这是一个例子:
预期结果:
<select datatag="data-States=''" class="form-control filter-select" data-multi-select="" id="States" multiple="multiple" name="States">
<optgroup label="MA">
<option value="01602">01602</option>
<option value="02743">02743</option>
<option value="01107">01107</option>
</optgroup>
</select>
实际结果:
<select datatag="data-States=''" class="form-control filter-select" data-multi-select="" id="States" multiple="multiple" name="States">
<optgroup label="MA">
<option value="01602">01602</option>
</optgroup>
<optgroup label="MA">
<option value="02743">02743</option>
</optgroup>
<optgroup label="MA">
<option value="01107">01107</option>
</optgroup>
</select>
方法:
public ManifestFilterDropDownItem ReturnManifestFilterDataBasedOnTotalDataSet(IEnumerable<ManifestTableItem> data, bool isUserASR) {
IEnumerable<SelectListGroup> stateGroups = data.Select(x => x.AddrState.ToUpper()).Distinct().Select(x => new SelectListGroup() {
Name = x
});
IList<SelectListItem> stateZipSelectListItems = data.GroupBy(x => x.AddrZip).Select(x => new SelectListItem() {
Text = string.IsNullOrWhiteSpace(x.Key) ? "Empty" : x.Key,
Value = string.IsNullOrWhiteSpace(x.Key) ? "" : x.Key,
Group = stateGroups.Where(y => y.Name == data.Where(p => p.AddrZip == x.Key).First().AddrState.ToUpper()).Single()
}).OrderBy(x => x.Group.Name).ToList();
var manifestItem = new ManifestFilterDropDownItem {
States = stateZipSelectListItems
return manifestItem;
}
视图模型:
using System.Collections.Generic;
using System.Web.Mvc;
namespace FSVendor.Models.Manifest {
public class ManifestFilterViewModel {
public ManifestFilterViewModel() {
}
public string Name { get; set; }
public string DataTag => $"data-{Name}=''";
public IEnumerable<SelectListItem> SelectListItems { get; set; }
}
}
查看:
@model FSVendor.Models.Manifest.ManifestFilterViewModel
<label>States:</label>
@Html.DropDownList(Model.Name, Model.SelectListItems, new { @class = "form-control filter-select", data_multi_select = "", multiple = "multiple", @Model.DataTag })
您的查询正在为每个 SelectListItem
创建一个新的 SelectListGroup
,即使每个 SelectListGroup
具有相同的值。
修改查询以对数据进行分组,然后为每个组创建一个新的SelectListGroup
// Initialize model
var model = new ManifestFilterDropDownItem
{
States = new List<SelectListItem>
}
var states = data.GroupBy(x => x.AddrState); // group by state
foreach (var group in states)
{
// Create a SelectListGroup
var optionGroup = new SelectListGroup() { Name = group.Key };
// Add SelectListItem's
foreach (var item in group)
{
model.States.Add(new SelectListItem()
{
Value = item.AddrZip,
Text = item.AddrZip,
Group = optionGroup
})
}
}
return model;
或者,您可以使用 SelectList
构造函数的重载之一
var model = new ManifestFilterDropDownItem
{
States = new SelectList(data, "AddrZip", "AddrZip", "AddrState", null, null)
};
return model;
附带说明一下,不要使用 DropDownList()
创建 <select multiple>
。您需要使用 ListBoxFor()
才能使 2 向模型绑定起作用。参考
我相信你的 ManifestTableItem
class 至少有这个结构:
class ManifestTableItem {
public string AddrState { get ; set ; }
public string AddrZip { get ; set ; }
}
要使状态在 selectlist
中显示为一个组,您需要使用此重载:
new SelectList(data, nameof(ManifestTableItem.AddrZip), nameof(ManifestTableItem.AddrZip), null, nameof(ManifestTableItem.AddrState));
我遇到一个问题,我正在用 optgroups
创建一个 List<SelectListItem>
,但不是为每组 SelectListItem
创建一个 optgroup
,而是创建一个新的SelectListGroup
每 SelectListItem
。这让我有点困惑,因为我的代码中没有任何重复的 SelectListGroup
。
这是一个例子:
预期结果:
<select datatag="data-States=''" class="form-control filter-select" data-multi-select="" id="States" multiple="multiple" name="States">
<optgroup label="MA">
<option value="01602">01602</option>
<option value="02743">02743</option>
<option value="01107">01107</option>
</optgroup>
</select>
实际结果:
<select datatag="data-States=''" class="form-control filter-select" data-multi-select="" id="States" multiple="multiple" name="States">
<optgroup label="MA">
<option value="01602">01602</option>
</optgroup>
<optgroup label="MA">
<option value="02743">02743</option>
</optgroup>
<optgroup label="MA">
<option value="01107">01107</option>
</optgroup>
</select>
方法:
public ManifestFilterDropDownItem ReturnManifestFilterDataBasedOnTotalDataSet(IEnumerable<ManifestTableItem> data, bool isUserASR) {
IEnumerable<SelectListGroup> stateGroups = data.Select(x => x.AddrState.ToUpper()).Distinct().Select(x => new SelectListGroup() {
Name = x
});
IList<SelectListItem> stateZipSelectListItems = data.GroupBy(x => x.AddrZip).Select(x => new SelectListItem() {
Text = string.IsNullOrWhiteSpace(x.Key) ? "Empty" : x.Key,
Value = string.IsNullOrWhiteSpace(x.Key) ? "" : x.Key,
Group = stateGroups.Where(y => y.Name == data.Where(p => p.AddrZip == x.Key).First().AddrState.ToUpper()).Single()
}).OrderBy(x => x.Group.Name).ToList();
var manifestItem = new ManifestFilterDropDownItem {
States = stateZipSelectListItems
return manifestItem;
}
视图模型:
using System.Collections.Generic;
using System.Web.Mvc;
namespace FSVendor.Models.Manifest {
public class ManifestFilterViewModel {
public ManifestFilterViewModel() {
}
public string Name { get; set; }
public string DataTag => $"data-{Name}=''";
public IEnumerable<SelectListItem> SelectListItems { get; set; }
}
}
查看:
@model FSVendor.Models.Manifest.ManifestFilterViewModel
<label>States:</label>
@Html.DropDownList(Model.Name, Model.SelectListItems, new { @class = "form-control filter-select", data_multi_select = "", multiple = "multiple", @Model.DataTag })
您的查询正在为每个 SelectListItem
创建一个新的 SelectListGroup
,即使每个 SelectListGroup
具有相同的值。
修改查询以对数据进行分组,然后为每个组创建一个新的SelectListGroup
// Initialize model
var model = new ManifestFilterDropDownItem
{
States = new List<SelectListItem>
}
var states = data.GroupBy(x => x.AddrState); // group by state
foreach (var group in states)
{
// Create a SelectListGroup
var optionGroup = new SelectListGroup() { Name = group.Key };
// Add SelectListItem's
foreach (var item in group)
{
model.States.Add(new SelectListItem()
{
Value = item.AddrZip,
Text = item.AddrZip,
Group = optionGroup
})
}
}
return model;
或者,您可以使用 SelectList
构造函数的重载之一
var model = new ManifestFilterDropDownItem
{
States = new SelectList(data, "AddrZip", "AddrZip", "AddrState", null, null)
};
return model;
附带说明一下,不要使用 DropDownList()
创建 <select multiple>
。您需要使用 ListBoxFor()
才能使 2 向模型绑定起作用。参考
我相信你的 ManifestTableItem
class 至少有这个结构:
class ManifestTableItem {
public string AddrState { get ; set ; }
public string AddrZip { get ; set ; }
}
要使状态在 selectlist
中显示为一个组,您需要使用此重载:
new SelectList(data, nameof(ManifestTableItem.AddrZip), nameof(ManifestTableItem.AddrZip), null, nameof(ManifestTableItem.AddrState));