如何将Repeater与对象列表GroupBy绑定

本文关键字:列表 GroupBy 绑定 对象 Repeater | 更新日期: 2023-09-27 18:15:36

首先,很抱歉说了这么久。但是有必要描述一下我的问题。每件事都是不言自明的,不那么难读。谢谢!

我有一个对象列表从我的类。List<CalendarEvent> allCalendarEvents = GetEvents();

public class CalendarEvent
{
    public int id { get; set; }
    public ID itemId { get; set; }
    public DateTime start { get; set; }
    public DateTime end { get; set; }
    public string subject { get; set; }
}

现在我想按start日期对列表allCalendarEvents中的事件进行分组。所以我使用了下面的代码:

var monthList = from e in allCalendarEvents
                group e by e.start.Month into g
                orderby g.Key
                select new { month = g.Key, Event = g };

列表中的所有项目现在按月分组。到目前为止一切顺利。我使用ASP Repeater向用户显示数据。

<asp:Repeater runat="server" ID="repMonths" OnItemDataBound="repMonths_OnItemDataBound">
    <ItemTemplate>
        <li>
            <%# Eval("month") %>

背后代码

repMonths.DataSource = monthList;
repMonths.DataBind();

我可以看到月份数字作为我的数据的输出,例如,对于五月,六月,七月的事件,我看到:

5
6
7

现在我想向用户显示在一个月份的组中有多少个CalenderEvents。如果我在repMonths中使用另一个中继器,像这样:

<asp:Repeater runat="server" ID="repMonths" OnItemDataBound="repMonths_OnItemDataBound">
    <ItemTemplate>
        <li>
            <%# Eval("month") %>
            <asp:Repeater runat="server" ID="repInnerEvent">
                <ItemTemplate>
                    <li>
                        <asp:Label runat="server" ID="lblEventName"></asp:Label>
                    </li>
                </ItemTemplate>
            </asp:Repeater>
        </li>
    </ItemTemplate>    
</asp:Repeater>

那么我不知道如何绑定数据与内部中继器。例如

protected void repMonths_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
    var item = e.Item.DataItem as ???; // I don't know what will come here
}

如何将Repeater与对象列表GroupBy绑定

您需要做的第一件事实际上是找到内部中继器。你在正确的轨道上。使用FindControl()在重复器项目找到它。然后,一旦您有了它,只需简单地分配数据源并绑定它。

protected void repMonths_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
    // We only care if the repeater item is part of the <ItemTemplate>
    if(e.Item.ItemType == ListItemType.Item)
    {
        Repeater repInnerEvent = (Repeater)e.Item.FindControl("repInnerEvent");
        repInnerEvent.DataSource = // your data source
        repInnerEvent.DataBind();
    }
}

听起来问题不在于如何绑定。它是如何获得绑定的数据。在这种情况下,您已经编写了查询。你只需要知道月份。在这种情况下,我将使用标签来保存月份。

<asp:Repeater runat="server" ID="repMonths" OnItemDataBound="repMonths_OnItemDataBound">
    <ItemTemplate>
        <li>
           <asp:Label ID="lblMonth" runat="server" Text='<%# Eval("month") %>'></asp:Label>
           <asp:Repeater runat="server" ID="repInnerEvent">
                <ItemTemplate>
                    <li>
                        <asp:Label runat="server" ID="lblEventName"></asp:Label>
                    </li>
                </ItemTemplate>
            </asp:Repeater>
        </li>
    </ItemTemplate>    
</asp:Repeater>

然后在ItemDataBound中,获取该标签并使用其值。

protected void repMonths_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
    // We only care if the repeater item is part of the <ItemTemplate>
    if(e.Item.ItemType == ListItemType.Item)
    {
        // Get the month
        Label lblMonth = (Label)e.Item.FindControl("lblMonth");
        // Get the events for the month
        var eventList = from e in allCalendarEvents
                        where e.start.Month == lblMonth.Text
                        select e;
        // Bind your events to the inner repeater
        Repeater repInnerEvent = (Repeater)e.Item.FindControl("repInnerEvent");
        repInnerEvent.DataSource = eventList
        repInnerEvent.DataBind();
    }
}