2

I have two repeaters, one nested in the other. I'm outputting a list of course titles in the parent repeater and the dates of those courses in the child repeater. This part is working fine. But, not all the course titles necessarily have dates available at any given time, so I want to be able to put a message up under each Course title that currently has no dates saying to check back regularly, blah, blah, blah. I've put the label in the footer template of the nested repeater with visibility=false and am trying to set the visibility=true at the appropriate time in the ItemDataBound Sub. Unfortunately, this is not working. I'm not getting any errors, the label just isn't showing up. I'm really hoping someone can help me out with my code or suggest an alternate way to do this. I'm kinda new to asp.net(VB) and am still struggling a bit. I've never tried nesting repeaters before. Here is my code:

.aspx

<asp:Repeater ID="rptTech" runat="server" >
            <HeaderTemplate>
                <table class="tableCourses">
            </HeaderTemplate>
            <ItemTemplate>
                <tr>
                    <td>
                        <strong><asp:Label runat="server" ID="lblCourseName" Text='<%# Eval("CourseName") %>'></asp:Label></strong>
                        <br />
                        <asp:Label runat="server" ID="lblCourseSummary" Text='<%# Eval("Summary") %>'></asp:Label>
                        <br />
                        <asp:HyperLink ID="hpCourseMaterial" Visible='<%# CheckCourseMaterial(Eval("CourseMaterial")) %>' NavigateUrl='<%# "/files/Portal_Course_Material/" & Eval("CourseMaterial")%>' Text="Download Course Material" runat="server"></asp:HyperLink>
                    </td>
                </tr>
                <tr>
                    <td>
                    <asp:Repeater ID="rptTechDates" DataSource='<%#Eval("relCourses") %>' runat="server" >
                        <HeaderTemplate>
                            <table>
                        </HeaderTemplate>
                        <ItemTemplate>
                            <tr>
                                <td>
                                    <strong><asp:Label runat="server" ID="lblDate" Text='<%# CDate(Eval("dteDate")).ToString("dd/MM/yyyy") %>'></asp:Label></strong><br />
                                    <asp:Label runat="server" ID="dteTime" Text='<%# "Time: " & CDate(Eval("dteTime2")).ToString("HH:mm") & " EST" %>'></asp:Label><br />
                                    <asp:HyperLink ID="Register" NavigateUrl='<%# "/Test.aspx?intMeetingID2=" & Eval("pkWebinarID")%>' Text="Register" runat="server"></asp:HyperLink>
                                </td>
                            </tr>
                        </ItemTemplate> 
                        <FooterTemplate>
                            <tr>
                                <td>
                                    <asp:Label ID="lblNoCourses" Text="There are no course dates available at this time. Please check back regularly to see any updates." runat="server" Visible="False"></asp:Label>
                                </td>
                            </tr>
                            </table>
                        </FooterTemplate>
                    </asp:Repeater>
                    </td>
                </tr>
            </ItemTemplate>
            <FooterTemplate>
                </table>
            </FooterTemplate>
        </asp:Repeater>

And Codebehind:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim curDate As Date = CDate(Now)

    'Create the connection
    Dim connstring As String
    connstring = ConfigurationManager.ConnectionStrings("LPISQLConn").ConnectionString

    Using conn As New SqlConnection(connstring)
        Dim cmd As New SqlCommand("SELECT foo1, foo2, foo3 FROM tblFoo", conn)
        cmd.CommandType = CommandType.Text

        Dim ad As New SqlDataAdapter(cmd)
        Dim ds As New DataSet()
        ad.Fill(ds)
        ds.Relations.Add(New DataRelation("relCourses", ds.Tables(0).Columns("fkcrsID"), ds.Tables(1).Columns("webinarID"), False))
        rptTech.DataSource = ds.Tables(0)
        rptTech.DataBind()
    End Using
End Sub

Protected Sub rptTech_ItemDataBound(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
    If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
        Dim drv As DataRowView = TryCast(e.Item.DataItem, DataRowView)
        Dim rptTechDates As Repeater = TryCast(e.Item.FindControl("rptTechDates"), Repeater)
        rptTechDates.DataSource = drv.CreateChildView("relCourses")
        If rptTechDates.Items.Count < 1 And rptTechDates IsNot Nothing Then
            If e.Item.ItemType = ListItemType.Footer Then
                Dim lblNoCourses As Label = TryCast(e.Item.FindControl("lblNoCourses"), Label)
                If lblNoCourses IsNot Nothing Then
                    lblNoCourses.Visible = True
                End If
            End If
        Else
            rptTechDates.DataBind()
        End If

    End If
End Sub
Wilock
  • 49
  • 6
  • If you haven't sorted this by tomorrow, I will help you. I have done this very recently but I don't have the tools at my disposal tonight to help you. – Jack Pettinger Apr 17 '13 at 21:31

2 Answers2

0

You want to search rptTechDates repeater for the lblNoCourses control. The e.Item.FindControl("lblNoCourses") is searching the rptTech repeater which doesn't exist. See this question to search the control in the rptTechDates footer.

Also, you'll want to call Databind() on the repeater after setting it's DataSource

rptTechDates.DataSource = drv.CreateChildView("relCourses")
rptTechDates.Databind()
Community
  • 1
  • 1
Ceres
  • 3,524
  • 3
  • 18
  • 25
0

I would do the following:

Change your ItemDataBoundEvent for the parent repeater to:

Protected Sub rptTech_ItemDataBound(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
  If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
      Dim drv As DataRowView = TryCast(e.Item.DataItem, DataRowView)
      Dim rptTechDates As Repeater = TryCast(e.Item.FindControl("rptTechDates"), Repeater)
      rptTechDates.DataSource = drv.CreateChildView("relCourses")
      rptTechDates.DataBind()
  End If
End Sub

Add this to the markup of your child repeater:

OnItemDataBound="rptTechDates_ItemDataBound"

Now add this:

Protected Sub rptTechDates_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)
If e.Item.ItemType = ListItemType.Footer Then
  If DirectCast(DirectCast(e.Item.NamingContainer, Repeater).DataSource, DataTable).Rows.Count = 0 Then
    DirectCast(e.Item.FindControl("lblNoCourses"), Label).Visible = True
  End If
End If

So, if the number of rows in the child repeater's datasource is 0, then show the label.

EDIT After comment from OP

Protected Sub rptTechDates_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs)
If e.Item.ItemType = ListItemType.Footer Then
  If DirectCast(DirectCast(e.Item.NamingContainer, Repeater).DataSource, DataView).Count = 0 Then
    DirectCast(e.Item.FindControl("lblNoCourses"), Label).Visible = True
  End If
End If
Jack Pettinger
  • 2,715
  • 1
  • 23
  • 37
  • Thanks for your response Jack! Getting the following error: Unable to cast object of type 'System.Data.RelatedView' to type 'System.Data.DataTable' on line: `If DirectCast(DirectCast(e.Item.NamingContainer, Repeater).DataSource, DataTable).Rows.Count = 0 Then` – Wilock Apr 18 '13 at 13:43
  • @Wilock I have updated my answer, can you try the bottom see if it works. – Jack Pettinger Apr 18 '13 at 14:09