Search code examples
c#asp.net.netrepeaternested-repeater

Exception while using nested repeaters


I have a datatable containing all my data called dtData. That datatable contains task descriptions with a task due date for every task description.

Here is what I want to do: The user selects the month and year from a dropdown and clicks on a button. Depending upon the number of days in the selected month, a number of panels are generated. (If there are 30 days, 30 panels are generated).

Each panel would correspond to a day in the month and would display the date accordingly. If the date displayed on the panel matches the task due date for my data, then the corresponding task description is to be displayed in the panel.

I have been able to render the calendar view as I want it but for some reason, while trying the following code to display the necessary task descriptions, a NullReferenceException is thrown. I debugged the code and the exception is thrown on the following line for the second time the loop which contains it is run (It runs perfectly fine the for the first time):

DateTime p_time = Convert.ToDateTime(((System.Data.DataRowView)(e.Item.DataItem)).Row.ItemArray[1]);

Here is my complete code:

My aspx:

<asp:Repeater ID="rptr_timeline" runat="server" OnItemDataBound="GetChildData">

    <ItemTemplate>

        <asp:Panel ID="pnl_timeline" runat="server" BackColor="LightGray" BorderColor="Black" BorderStyle="Solid" BorderWidth="1px">

        &nbsp;<span id="span_day">Day</span>&nbsp;<asp:Label ID="lbl_day_number" runat="server" Text='<%# Eval("Day_Number").ToString() %>'></asp:Label>&nbsp;&nbsp;

        <span id="span_date">Date:</span>&nbsp;<asp:Label ID="lbl_day_date" runat="server" Text='<%# Eval("Day_Date").ToString() %>'></asp:Label>&nbsp;&nbsp;

        <asp:Label ID="lbl_day_name" runat="server" Text='<%# Eval("Day_Name").ToString() %>'></asp:Label><br />

        <asp:Repeater ID="rptr_tasks" runat="server">
            <ItemTemplate>
                <asp:Label ID="lbl_task_name" runat="server" Text='<%# Eval("taskdescription_responsible").ToString() %>'></asp:Label>
            </ItemTemplate>
            <SeparatorTemplate>
                <br /><br />
            </SeparatorTemplate>
        </asp:Repeater>

        </asp:Panel>

    </ItemTemplate>
    <SeparatorTemplate>
        <br />
    </SeparatorTemplate>
</asp:Repeater>

And here is my code behind:

protected void Load_Dateline(object sender, EventArgs e)
{
    try
    {
        int counter = 0;
        int months_days_number = 0;
        int month_selected = 0;
        int year_selected = 0;

        month_selected = Convert.ToInt32(drpdwn_month.SelectedItem.Value);
        year_selected = Convert.ToInt32(drpdwn_year.SelectedItem.Value);

        months_days_number = DateTime.DaysInMonth(year_selected, month_selected);

        DataTable dtMonthdays = new DataTable();
        dtMonthdays.Columns.Add("Day_Number");
        dtMonthdays.Columns.Add("Day_Date");
        dtMonthdays.Columns.Add("Day_Name");
        dtMonthdays.Columns.Add("ProperDate");

        for (counter = 1; counter <= months_days_number; counter++)
        {
            DataRow new_row = dtMonthdays.NewRow();
            if (counter < 10)
            {
                new_row["Day_Number"] = "0" + counter.ToString();
            }
            else
            {
                new_row["Day_Number"] = counter.ToString();
            }
            new_row["Day_Date"] = counter.ToString() + "/" + drpdwn_month.SelectedItem.Value.ToString() + "/" + year_selected.ToString();

            DateTime temp_date = new DateTime(year_selected, month_selected, counter);

            new_row["Day_Name"] = temp_date.ToString("dddd");

            dtMonthdays.Rows.Add(new_row);

        }

        rptr_timeline.DataSource = dtMonthdays;
        rptr_timeline.DataBind();
    }
    catch (Exception ex)
    {
        lbl_error.Text = "Something went wrong!<br /><br />" + ex.ToString();
    }
}

And the following is called on OnItemDataBound of parent repeater:

protected void GetChildData(Object sender, RepeaterItemEventArgs e)
{
    Repeater nestedRepeater = e.Item.FindControl("rptr_tasks") as Repeater;
    DataTable dt_new = dtData.Clone();

    DateTime p_time = Convert.ToDateTime(((System.Data.DataRowView)(e.Item.DataItem)).Row.ItemArray[1]);

    foreach (DataRow dr in dtData.Rows)
    {
        if (DateTime.Parse(dr["taskduedate_responsible"].ToString()).Equals(p_time.ToString()))
        {
            dt_new.ImportRow(dr);
        }
    }

    if (dt_new != null && dt_new.Rows.Count != 0)
    {
        nestedRepeater.DataSource = dt_new;
        nestedRepeater.DataBind();
    }
}

Solution

  • add check whether currently binding item is an Item. or AlternateItem in your GetChildData method

    protected void GetChildData(Object sender, RepeaterItemEventArgs e)
    {
      if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) 
      {
        //Do binding
      }
    
    }