Asp.net webforms ListBox分组

时间:2015-05-11 17:03:02

标签: c# asp.net listbox optgroup

我有一个webform页面,上面有一个Listbox,上面有一个摄像头列表。它由一个数据表填充,该数据表包含摄像机名称,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();
        }
    }

该代码可以很好地使用摄像机名称填充列表框,但我想使它具有该组,然后是该组中的摄像机。我不知道该怎么做。我学会了不要在这里问问题,除非我绝对必须这样做,但是我已经研究了几天而找不到任何东西。这可能吗?我是否必须以编程方式完成所有这些操作?

1 个答案:

答案 0 :(得分:1)

基于SO答案的一个很好的方法: How can I add option groups in ASP.NET drop down list?

ASP.NET中的ListBox不支持执行您请求的分组所需的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;
        }
    }
}