views:

773

answers:

2

I'm going to be developing an events calendar page which will display a list of events for 12 months from the current date (it will be read-only). It's easy enough to grab the data from the DB with a SP passing in the start date and number of months etc, but I need to group the information by month when it is displayed in the page. e.g. :


================================
June 2009
================================
Event 1
1 June 2009 to 2 June 2009
Event info
--------------------------------
Event 2
20 June 2009 to 21 June 2009
Event info
================================
July 2009
================================
Event 3
1 July 2009 to 2 July 2009
Event info
--------------------------------

...some more months/events here...

================================
May 2010
================================
Event 99
10 May 2010 to 11 May 2010
Event info
--------------------------------

I've seen other posts where people talk about nesting GridViews within Repeaters and vice versa but am unsure how I would achieve the grouping by month using this method.

+1  A: 

Bind your repeater to something that enumerates the months. Put a grid view in the item template of the repeater. In the ItemDataBound event of the repeater bind the gridview to something that enumerates all the events for that month. You can get the month from the RepeaterItemEventArgs.Item.DataItem object that holds the item that is being bound to the repeater item.

    <asp:Repeater ID="Repeater1" runat="server" 
        onitemdatabound="Repeater1_ItemDataBound">
    <ItemTemplate>
        <asp:GridView ID="GridView1" runat="server">
        </asp:GridView>
    </ItemTemplate>
    </asp:Repeater>



protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    GridView gridview = e.Item.FindControl("GridView1") as GridView;
    gridview.DataSource = ...;
    gridview.DataBind();
}

EDIT: Updated to show how the range of months is generated.

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        DateTime currentDate = DateTime.Now;
        DateTime startDate = new DateTime(currentDate.Year, currentDate.Month, 1); 
        List<DateTime> dateRange = new List<DateTime>();
        for (int i = 0; i < 12; i++)
            dateRange.Add(startDate.AddMonths(i));

        Repeater1.DataSource = dateRange;
        Repeater1.DataBind();
    }
}
Locutus
A: 

Basically a GridView is a table, using tables within Repeaters do just fine, you should consider this in conjunction with DataBinder.Eval such as:

<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
        <ItemTemplate>
            <table>
                <caption><%# Eval("MONTH") %></caption>
                <tr>
                    <td><%# Eval("EVENT_NAME") %></td>
                </tr>
                <tr>
                    <td><%# Eval("DATE_BEGIN") %> to <%# Eval("DATE_END") %></td>
                </tr>
                <tr>
                    <td><%# Eval("EVENT_INFO") %></td>
                </tr>
            </table>
        </ItemTemplate>
    </asp:Repeater>

Obliviously this would create a table for each event. You could as well start the table in the <HeaderTemplate> and finish it in the FooterTemplate.

Now all you need is to to return the data accordingly.

Good luck.

Maxime
This doesn't satisfy the need to group events by month though? i.e. if there are 2 events in June I don't want to display the heading 'June 2009' more than once.
mdresser
Nested Repeater would by the solution. Basically a Repeater inside the first one's ItemTemplate, overriding the first Repeater's OnItemDataBound.See:http://www.dotnetspider.com/resources/744-Using-Nested-Repeater-Controls.aspxhttp://www.codeproject.com/KB/aspnet/AspNetNestedRepeaters.aspxhttp://www.voidnish.com/articles/ShowArticle.aspx?code=AspNetNestedRepeatersAlright, notice the CreateChildView method.Good luck!
Maxime