Asp.net webforms 列表框分组
Asp.net webforms ListBox Grouping
我有一个网络表单页面,上面有一个列表框,上面有一个摄像机列表。它由一个数据表填充,该数据表有一列用于摄像机名称、IP 地址和组。
DataClasses1DataContext dc = new DataClasses1DataContext();
public List<CameraTable> CameraListBox;
public List<ListItem> SelectedListBox;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CameraListBox = (from x in dc.CameraTables
select x).ToList();
ListBox1.DataSource = CameraListBox;
ListBox1.DataTextField = "CameraName";
ListBox1.DataValueField = "IPAddress";
ListBox1.DataBind();
}
}
该代码可以很好地用相机名称填充列表框,但我想这样做,以便它具有组,然后是该组中的相机。我不知道该怎么做。除非绝对必要,否则我学会了不要在这里提问,但我已经研究了几天但找不到任何东西。这可能吗?我必须以编程方式完成所有这些吗?
基于 SO answer 的一个很好的方法:
How can I add option groups in ASP.NET drop down list?
ASP.NET 中的列表框不支持执行您请求的分组所需的 optgroup
html。注入此功能的一种方法是向列表项添加属性以捕获类别,然后使用您最喜欢的前端框架修改 DOM 以构建适当的 optgroup
结构。
由于 ListBox 控件没有 OnItemDataBound
类型的事件,您无法在数据绑定过程中访问每个项目。由于那将是您唯一一次可以访问 CameraTable 记录的 group
,因此您不能进行数据绑定 - 您必须自己构建列表,以便可以将组作为 html 属性添加到每个选项。
如果可能,下面的方法是创建具有数据属性的单个列表项的帮助程序。
public ListItem GetListItem(CameraTable item)
{
var listItem = new ListItem(item.CameraName, item.IPAddress);
if (string.IsNullOrEmpty(item.GroupName) == false)
listItem.Attributes.Add("data-category", item.GroupName);
return listItem;
}
然后,直接构建列表框,而不是列表框上的数据绑定代码。您必须考虑跨回发的视图状态和持久性,但这至少是方法:
var itemsToAdd = CameraListBox
.Select(c => GetListItem(c))
.ToArray();
ListBox1.Items.AddRange(itemsToAdd);
最后,拉出您最喜欢的客户端框架(下面的JQuery)来构建 optgroup 元素。
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 + '">');
});
这应该完成了元素的分组。
根据评论问题更新
如果您要将它放在 html 的头部,您必须确保 DOM 已加载 - 否则您正在操作尚未准备好的元素。
为了在此处保留 JQuery,请将客户端脚本包装在 $(document).ready
事件中。我在下面包含了一个完整的示例页面。
ASPX 页面
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Web.WebForm1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
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 + '">');
});
});
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="BodyContent" runat="server">
<asp:ListBox ID="ListBox1" runat="server" Height="100" Width="200" />
</asp:Content>
ASPX 代码隐藏(具有模拟数据上下文和相机表)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
namespace Web
{
public partial class WebForm1 : System.Web.UI.Page
{
DataClasses1DataContext dc = new DataClasses1DataContext();
public List<CameraTable> CameraListBox;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CameraListBox = (from x in dc.CameraTables
select x).ToList();
var itemsToAdd = CameraListBox
.Select(c => GetListItem(c))
.ToArray();
ListBox1.Items.AddRange(itemsToAdd);
}
}
public ListItem GetListItem(CameraTable item)
{
var listItem = new ListItem(item.CameraName, item.IPAddress);
if (string.IsNullOrEmpty(item.GroupName) == false)
listItem.Attributes.Add("data-category", item.GroupName);
return listItem;
}
}
public class DataClasses1DataContext
{
public IQueryable<CameraTable> CameraTables
{
get
{
return new List<CameraTable>()
{
new CameraTable("Back Hallway", "1.1.1.1", "Floor 1"),
new CameraTable("Bedroom 1", "2.2.2.2", "Floor 1"),
new CameraTable("Bedroom 2", "3.3.3.3", "Floor 2"),
}.AsQueryable();
}
}
}
public class CameraTable
{
public string CameraName { get; set; }
public string IPAddress { get; set; }
public string GroupName { get; set; }
public CameraTable(string name, string ip, string group)
{
this.CameraName = name;
this.IPAddress = ip;
this.GroupName = group;
}
}
}
我有一个网络表单页面,上面有一个列表框,上面有一个摄像机列表。它由一个数据表填充,该数据表有一列用于摄像机名称、IP 地址和组。
DataClasses1DataContext dc = new DataClasses1DataContext();
public List<CameraTable> CameraListBox;
public List<ListItem> SelectedListBox;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CameraListBox = (from x in dc.CameraTables
select x).ToList();
ListBox1.DataSource = CameraListBox;
ListBox1.DataTextField = "CameraName";
ListBox1.DataValueField = "IPAddress";
ListBox1.DataBind();
}
}
该代码可以很好地用相机名称填充列表框,但我想这样做,以便它具有组,然后是该组中的相机。我不知道该怎么做。除非绝对必要,否则我学会了不要在这里提问,但我已经研究了几天但找不到任何东西。这可能吗?我必须以编程方式完成所有这些吗?
基于 SO answer 的一个很好的方法: How can I add option groups in ASP.NET drop down list?
ASP.NET 中的列表框不支持执行您请求的分组所需的 optgroup
html。注入此功能的一种方法是向列表项添加属性以捕获类别,然后使用您最喜欢的前端框架修改 DOM 以构建适当的 optgroup
结构。
由于 ListBox 控件没有 OnItemDataBound
类型的事件,您无法在数据绑定过程中访问每个项目。由于那将是您唯一一次可以访问 CameraTable 记录的 group
,因此您不能进行数据绑定 - 您必须自己构建列表,以便可以将组作为 html 属性添加到每个选项。
如果可能,下面的方法是创建具有数据属性的单个列表项的帮助程序。
public ListItem GetListItem(CameraTable item)
{
var listItem = new ListItem(item.CameraName, item.IPAddress);
if (string.IsNullOrEmpty(item.GroupName) == false)
listItem.Attributes.Add("data-category", item.GroupName);
return listItem;
}
然后,直接构建列表框,而不是列表框上的数据绑定代码。您必须考虑跨回发的视图状态和持久性,但这至少是方法:
var itemsToAdd = CameraListBox
.Select(c => GetListItem(c))
.ToArray();
ListBox1.Items.AddRange(itemsToAdd);
最后,拉出您最喜欢的客户端框架(下面的JQuery)来构建 optgroup 元素。
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 + '">');
});
这应该完成了元素的分组。
根据评论问题更新
如果您要将它放在 html 的头部,您必须确保 DOM 已加载 - 否则您正在操作尚未准备好的元素。
为了在此处保留 JQuery,请将客户端脚本包装在 $(document).ready
事件中。我在下面包含了一个完整的示例页面。
ASPX 页面
<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Web.WebForm1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
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 + '">');
});
});
</script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="BodyContent" runat="server">
<asp:ListBox ID="ListBox1" runat="server" Height="100" Width="200" />
</asp:Content>
ASPX 代码隐藏(具有模拟数据上下文和相机表)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
namespace Web
{
public partial class WebForm1 : System.Web.UI.Page
{
DataClasses1DataContext dc = new DataClasses1DataContext();
public List<CameraTable> CameraListBox;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CameraListBox = (from x in dc.CameraTables
select x).ToList();
var itemsToAdd = CameraListBox
.Select(c => GetListItem(c))
.ToArray();
ListBox1.Items.AddRange(itemsToAdd);
}
}
public ListItem GetListItem(CameraTable item)
{
var listItem = new ListItem(item.CameraName, item.IPAddress);
if (string.IsNullOrEmpty(item.GroupName) == false)
listItem.Attributes.Add("data-category", item.GroupName);
return listItem;
}
}
public class DataClasses1DataContext
{
public IQueryable<CameraTable> CameraTables
{
get
{
return new List<CameraTable>()
{
new CameraTable("Back Hallway", "1.1.1.1", "Floor 1"),
new CameraTable("Bedroom 1", "2.2.2.2", "Floor 1"),
new CameraTable("Bedroom 2", "3.3.3.3", "Floor 2"),
}.AsQueryable();
}
}
}
public class CameraTable
{
public string CameraName { get; set; }
public string IPAddress { get; set; }
public string GroupName { get; set; }
public CameraTable(string name, string ip, string group)
{
this.CameraName = name;
this.IPAddress = ip;
this.GroupName = group;
}
}
}