我需要在ASP.NET下拉服务器控件中对下拉列表选项进行分组。你对如何处理这个问题有任何想法吗?我是ASP.NET的新手。
答案 0 :(得分:36)
查看这篇文章,我也需要Group DropDown列表。 。
ASP.NET DropDownList with OptionGroup support
用法:
protected void Page_Load(object sender, EventArgs e)
{
ListItem item1 = new ListItem("Camel", "1");
item1.Attributes["OptionGroup"] = "Mammals";
ListItem item2 = new ListItem("Lion", "2");
item2.Attributes["OptionGroup"] = "Mammals";
ListItem item3 = new ListItem("Whale", "3");
item3.Attributes["OptionGroup"] = "Mammals";
ListItem item4 = new ListItem("Walrus", "4");
item4.Attributes["OptionGroup"] = "Mammals";
ListItem item5 = new ListItem("Velociraptor", "5");
item5.Attributes["OptionGroup"] = "Dinosaurs";
ListItem item6 = new ListItem("Allosaurus", "6");
item6.Attributes["OptionGroup"] = "Dinosaurs";
ListItem item7 = new ListItem("Triceratops", "7");
item7.Attributes["OptionGroup"] = "Dinosaurs";
ListItem item8 = new ListItem("Stegosaurus", "8");
item8.Attributes["OptionGroup"] = "Dinosaurs";
ListItem item9 = new ListItem("Tyrannosaurus", "9");
item9.Attributes["OptionGroup"] = "Dinosaurs";
ddlItems.Items.Add(item1);
ddlItems.Items.Add(item2);
ddlItems.Items.Add(item3);
ddlItems.Items.Add(item4);
ddlItems.Items.Add(item5);
ddlItems.Items.Add(item6);
ddlItems.Items.Add(item7);
ddlItems.Items.Add(item8);
ddlItems.Items.Add(item9);
}
答案 1 :(得分:35)
我真的很喜欢这个客户端解决方案(不需要自定义DropDownList,但使用jQuery):
<强>后端强>
private void _addSelectItem(DropDownList list, string title, string value, string group = null) {
ListItem item = new ListItem(title, value);
if (!String.IsNullOrEmpty(group))
{
item.Attributes["data-category"] = group;
}
list.Items.Add(item);
}
...
_addSelectItem(dropDown, "Option 1", "1");
_addSelectItem(dropDown, "Option 2", "2", "Category");
_addSelectItem(dropDown, "Option 3", "3", "Category");
...
<强>客户端强>
var groups = {};
$("select option[data-category]").each(function () {
groups[$.trim($(this).attr("data-category"))] = true;
});
$.each(groups, function (c) {
$("select option[data-category='"+c+"']").wrapAll('<optgroup label="' + c + '">');
});
答案 2 :(得分:5)
这是旧的,但由于我最近使用了接受的答案,我想与大家分享一下我的经验。虽然它确实提供了正确的标记,但它给我带来了问题,特别是当我尝试使用任何下拉列表提交表单时,我会得到可怕的回复或回调参数#34;错误。在像疯子一样谷歌搜索后,我遇到了this article,然后链接到this blog post。我最终使用的代码是:
public class DropDownListAdapter : System.Web.UI.WebControls.Adapters.WebControlAdapter {
protected override void RenderContents(HtmlTextWriter writer) {
var dropDownList = (DropDownList)Control;
var items = dropDownList.Items;
var groups = (from p in items.OfType<ListItem>()
group p by p.Attributes["Group"] into g
select new { Label = g.Key, Items = g.ToList() });
foreach (var group in groups)
{
if (!String.IsNullOrEmpty(group.Label))
{
writer.WriteBeginTag("optgroup");
writer.WriteAttribute("label", group.Label);
writer.Write(">");
}
var count = group.Items.Count();
if (count > 0)
{
var flag = false;
for (var i = 0; i < count; i++)
{
var item = group.Items[i];
writer.WriteBeginTag("option");
if (item.Selected)
{
if (flag)
{
throw new HttpException("Multiple selected items not allowed");
}
flag = true;
writer.WriteAttribute("selected", "selected");
}
if (!item.Enabled)
{
writer.WriteAttribute("disabled", "true");
}
writer.WriteAttribute("value", item.Value, true);
if (Page != null)
{
Page.ClientScript.RegisterForEventValidation(dropDownList.UniqueID, item.Value);
}
writer.Write('>');
HttpUtility.HtmlEncode(item.Text, writer);
writer.WriteEndTag("option");
writer.WriteLine();
}
}
if (!String.IsNullOrEmpty(group.Label))
{
writer.WriteEndTag("optgroup");
}
}
}
}
这里使用的列表项是在设计页面而不是代码隐藏页面中创建的,如下所示:
<asp:ListItem Value="apple" Text="Apple" Group="Fruit"></asp:ListItem>
<asp:ListItem Value="banana" Text="Banana" Group="Fruit"></asp:ListItem>
<asp:ListItem Value="asparagus" Text="Asparagus" Group="Vegetable"></asp:ListItem>
<asp:ListItem Value="eggs" Text="Eggs" Group="Dairy"></asp:ListItem>
这产生了与此处接受的答案相同的标记,但这并没有给我回发错误。我希望这可以为某人带来一些悲伤。
答案 3 :(得分:2)
----- in .cs -----
List<SelectListItem> sl = new List<SelectListItem>();
sl.Add(new SelectListItem() { Text = "My text", Value = "1", Group = new SelectListGroup() { Name = "First Group" } });
sl.Add(new SelectListItem() { Text = "My text 2", Value = "2", Group = new SelectListGroup() { Name = "First Group" } });
var sl1 = new SelectList(sl,"Value","Text","Group.Name",-1);
ViewData["MyList"] = sl1;
----- in .cshtml -----
Html.DropDownList("My List", ViewData["MyList"] as SelectList,
"-- No Preference --",
new {
@class = "ui-widget ui-corner-all square_corners searchPageDropdown"
}))
答案 4 :(得分:2)
1)将下拉列表适配器类从here添加到您的项目
2)将App_Browsers文件夹添加到项目中(右键单击project =&gt; Add =&gt;添加ASP.NET文件夹=&gt; App_Browsers)
3)将浏览器文件添加到App_Browsers页面,并在浏览器标记内添加以下代码。
<browser refID="WebKit">
<controlAdapters>
<adapter controlType="System.Web.UI.WebControls.DropDownList"
adapterType="YourAdapterClasse'sNameSPace.DropDownListAdapter" />
</controlAdapters>
</browser>
refId = WebKit支持chrome和safari浏览器
4)然后您可以将项目添加到下拉列表中 ListItem item1 = new ListItem(&#34; Smith Street&#34;,&#34; 1&#34;); item1.Attributes [&#34; OptionGroup&#34;] =&#34;达尔文&#34 ;;
ListItem item2 = new ListItem("Mitchel Street", "1");
item2.Attributes["OptionGroup"] = "Darwin";
ListItem item3 = new ListItem("Hunter Street", "2");
item3.Attributes["OptionGroup"] = "Sydney";
ListItem item4 = new ListItem("BroadwaY", "4");
item4.Attributes["OptionGroup"] = "Sydney";
venuedropdown.Items.Add(item1);
venuedropdown.Items.Add(item2);
venuedropdown.Items.Add(item3);
venuedropdown.Items.Add(item4);
答案 5 :(得分:1)
这就是我所做的,仅使用jquery,没有服务器端更改:
/* Add Option Groups to Note Dropdown */
var $select = $('#<%= DropDownListIDHere.ClientID %>');
var optGroup;
$('#<%= DropDownListIDHere.ClientID %> option').each(function () {
if ($(this).val() == '<') {
/* Opener */
optGroup = $('<optGroup>').attr('label', $(this).text());
} else if ($(this).val() == '>') {
/* Closer */
$('</optGroup>').appendTo(optGroup);
optGroup.appendTo($select);
optGroup = null;
} else {
/* Normal Item */
if (optGroup) {
$('<option>' + $(this).text() + '</option>').attr('value', $(this).val()).appendTo(optGroup);
} else {
$('<option>' + $(this).text() + '</option>').attr('value', $(this).val()).appendTo($select);
}
}
$(this).remove();
});
然后,您只需将特定项目添加为值为&lt;的开启者和关闭者。和&gt;像这样:
<asp:ListItem Text="Group 1" Value="<" />
<asp:ListItem Text="Thing 1" Value="1111" />
<asp:ListItem Text="Thing 2" Value="2222" />
<asp:ListItem Text="Thing 3" Value="3333" />
<asp:ListItem Text="Group 1" Value=">" />
超级简单,无需新控件,仅针对您想要更改的选项,并且不要求每个项目都在optgroup中。
答案 6 :(得分:0)
我使用此方法,避免使用ViewBag和ViewData:
查看型号:
public class PageViewModel
{
public int SelectedDropdownItem { get; set; }
public IEnumerable<SelectListItem> DropdownList { get; set; }
}
示例实体模型(对于此示例):
public class Users
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsAdministrator { get; set; }
public bool IsDefault { get; set; }
}
<强>控制器:强>
// Get list for the dropdown (this uses db values)
var userList = db.Users.ToList();
// Define the Groups
var group1 = new SelectListGroup { Name = "Administrators" };
var group2 = new SelectListGroup { Name = "Users" };
// Note - the -1 is needed at the end of this - pre-selected value is determined further down
// Note .OrderBy() determines the order in which the groups are displayed in the dropdown
var dropdownList = new SelectList(userList.Select(item => new SelectListItem
{
Text = item.Name,
Value = item.Id,
// Assign the Group to the item by some appropriate selection method
Group = item.IsAdministrator ? group1 : group2
}).OrderBy(a => a.Group.Name).ToList(), "Value", "Text", "Group.Name", -1);
// Assign values to ViewModel
var viewModel = new PageViewModel
{
// Assign the pre-selected dropdown value by appropriate selction method (if needed)
SelectedDropdownItem = userList.FirstOrDefault(a => a.IsDefault).Id,
DropdownList = dropdownList
};
查看:强>
<!-- If needed, change 'null' to "Please select item" -->
@Html.DropDownListFor(a => a.SelectedDropdownItem, Model.DropdownList, null, new { @class = "some-class" })
希望这有助于某人避免发生在我身上的事情 - 花费太多时间来寻找一种强类型的方法。
答案 7 :(得分:0)
如果有多个选择标记,mhu's excellent solution的客户端的这一小改进也会有效。
事实上,对于他的版本,每个选择标签都会填充每个选择标签的每个选项标签的一个副本
(在此示例中,.select2是所有选择标记的共同类)
function filterUserGroups()
{
var groups = {};
$("select option[data-category]").each(function () {
var sGroup = $.trim($(this).attr("data-category"));
groups[sGroup] = true;
});
$.each(groups, function (c) {
$(".select2").each(function () {
$(this).find("option[data-category='" + c + "']").wrapAll('<optgroup label="' + c + '">');
})
});
}
答案 8 :(得分:0)
我更喜欢客户端脚本解决方案,以避免回发时的复杂性,所以我这样解决了。这里我使用普通的html选择只是为了在函数中显示它,但它也适用于ASP DropDownList:
<script>
function addOptGrp() {
var t, p
for (var i = 0; i < arguments.length; i=i+2) {
t=arguments[i];
p=arguments[i+1]-i/2;
var scripts = document.getElementsByTagName('script');
/* On the next line scripts[scripts.length - 1] is the last script
in the page, which by definition will always be the calling script,
no matter how many such scripts you have */
var ddl = scripts[scripts.length - 1].previousElementSibling;
var og = document.createElement("optgroup");
og.label = t;
ddl.add(og,p);
ddl.selectedIndex = ddl.selectedIndex // needed for UI;
}
}
</script>
<select style="width:100px;">
<option>Apple</option>
<option>Pear</option>
<option>Banana</option>
<option>Orange</option>
</select>
<!-- here I just add the option groups in a script that immediately executes.
Notice that the script must follow immediately after the select (or DropDownList) -->
<script>addOptGrp(
'Simple fruits', 0,
'Very exotic fruits', 3
)</script>
<br><br>
<!-- Here comes another one -->
<select style="width:100px;">
<option>Red</option>
<option>Blue</option>
<option>Yellow</option>
<option>Green</option>
<option>Magenta</option>
<option>White</option>
</select>
<script>addOptGrp(
'Some colors', 0,
'Some more colors', 4
)</script>
这个功能满足了我今天的需求。另一天可能需要使用修改版本,例如,它将普通选项转换为optgroups,具体取决于某些前缀左右。
答案 9 :(得分:0)
我真的很喜欢@ScottRFrost的回答。但是,在撰写本文时,它比我的工作量少了两块:
这是我对他的回答的扩展:
$(document).ready(function () {
ddlOptionGrouping();
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(ddlOptionGrouping);
function ddlOptionGrouping() {
/* Add Option Groups to asp:DropdownList */
var $select = $('#<%= aspDropDownList.ClientID %>');
var optGroup;
$('#<%= aspDropDownList.ClientID %> option').each(function () {
if ($(this).val() == '<') {
/* Opener */
optGroup = $('<optGroup>').attr('label', $(this).text());
} else if ($(this).val() == '>') {
/* Closer */
$('</optGroup>').appendTo(optGroup);
optGroup.appendTo($select);
optGroup = null;
} else {
/* Normal Item */
let $option = $('<option>' + $(this).text() + '</option>').attr('value', $(this).val());
if (this.hasAttribute('selected')) {
$option.attr('selected', $(this).attr('selected'));
}
if (optGroup) {
$option.appendTo(optGroup);
} else {
$option.appendTo($select);
}
}
$(this).remove();
});
}
});