Хотите получить доступ к элементам управления в динамически созданном вложенном повторителе

#asp.net #vb.net #repeater

#asp.net #vb.net #повторитель

Вопрос:

Я искал повсюду решение и прошел через свой код, но, похоже, я не могу найти свой childRepeater в событии нажатия кнопки. Кнопка помещается в нижний колонтитул familyRepeater, если это имеет значение для этой проблемы.

Дочерний элемент создается динамически в коде.

Вот мое событие щелчка:

   Protected Sub EnrollAllButton_Click(sender As Object, e As EventArgs)

    familyRepeater.DataSource = Session("Families")
    familyRepeater.DataBind()
    
    For Each item As RepeaterItem In familyRepeater.Items
      If (item.ItemType = ListItemType.Item OrElse item.ItemType = ListItemType.AlternatingItem) Then

        ' this never finds childRepeater. It is null for every item
        Dim childRepeater As Repeater = TryCast(item.FindControl("childRepeater"), Repeater)

        If childRepeater IsNot Nothing Then

          For Each child As RepeaterItem In childRepeater.Items
            Dim radio1 As RadioButtonList = CType(child.FindControl("AttendanceRBL"), RadioButtonList)
            radio1.Items.FindByText("Enrolled").Selected = True

          Next
        End If
      End If
    Next
  End Sub
 

Чего мне не хватает, чтобы добраться до дочернего повторителя и его элементов управления? Когда я просматриваю страницу в браузере, я могу перейти к дочернему повторителю и увидеть там все дочерние элементы управления.

Вот моя страница aspx:

 <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Repeater.aspx.vb" Inherits="RepeaterSample.Repeater" enableEventValidation="false" %>

<%@ Import Namespace="System.Data" %>

<html>

<head runat="server">
    <title></title>
    <link href="~/StyleSheet1.css" rel="stylesheet" type="text/css" />
</head>
  
<body>
  <form runat="server">

    <div id="NestedRepeaters">
      <p>Repeater: </p>
      <p>Family: <asp:Label ID="familyMsg" runat="server" Text="ViewMode"></asp:Label></p>
       <p>Child: <asp:Label ID="childMsg" runat="server" Text=""></asp:Label></p>

      <!-- begin parent repeater -->
      <asp:Repeater ID="familyRepeater" runat="server" OnItemCommand="familyRepeater_ItemCommand" >
        <HeaderTemplate>
          <table >
            <tr>
              <th colspan="4"><asp:Label runat="server" Text="Last Name, First Name, M.I." Font-Bold="true" Width="300"></asp:Label></th>
              <th><asp:Label runat="server" Text="FICN" Font-Bold="true" Width="100"></asp:Label></th>
              <th><asp:Label runat="server" Text="Program Code" Font-Bold="true" Width="100"></asp:Label></th>
              <th colspan="2"><asp:Label runat="server" Text="Attendance Status" Font-Bold="true" Width="200"></asp:Label></th>
              <th><asp:Label runat="server" Text="Update" Font-Bold="true" Width="80"></asp:Label></th>
            </tr>
        </HeaderTemplate>
        <ItemTemplate>
          <tr class="spaceAbove">
            <td><b>Family:</b></td>
            <td colspan="3"><%# DataBinder.Eval(Container.DataItem, "FamilyName") %></td>
            <td><%# DataBinder.Eval(Container.DataItem, "FICN") %> </td>
            <td></td>
            <td></td>
            <td></td>          
            <td style="text-align: center;"> 
    
           <asp:LinkButton ID="editFamily" runat="server" Text="Edit Family" OnClick="OnEdit" CommandName="EditFamily" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "FamilyID") %>' ></asp:LinkButton>
                <asp:LinkButton ID="updateFamily" Text="Update" runat="server" Visible="false" OnClick="OnUpdate" CommandName="UpdateFamily"/>
                <asp:LinkButton ID="cancelFamily" Text="Cancel" runat="server" Visible="false" OnClick="OnCancel" CommandName="CancelFamily" />
             
            </td>
          </tr>
          <!-- begin child repeater -->
          <asp:Repeater ID="childRepeater" runat="server" OnItemDataBound="ChildRepeater_ItemDataBound" DataSource='<%# (CType(Container.DataItem, DataRowView)).Row.GetChildRows("FamilyChildRelation") %>' OnItemCommand="ChildRepeater_ItemCommand" >
            <ItemTemplate>
              <tr>
                <td></td>
                <td colspan="4" style="vertical-align: top;">Child: <asp:Label runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "ChildName") %>' />
                </td>
                <td style="text-align: center;">
                  <asp:PlaceHolder ID="programPlaceHolder" runat="server" ></asp:PlaceHolder>
                </td>
                <td style="text-align: center;">
                  <asp:PlaceHolder ID="attendancePlaceHolder" runat="server" ></asp:PlaceHolder>
                </td>
                <td></td>
                <td ></td>
              </tr>       
            </ItemTemplate>
          </asp:Repeater>
          <!-- end child repeater -->
        </ItemTemplate>
        <FooterTemplate> 
          <td colspan ="4" style="text-align: center; ">
          <asp:button ID="EnrollAllButton" runat="server" text="Enroll All" OnClick="EnrollAllButton_Click" />
          <asp:button ID="AttendAllButton" runat="server" text="Attend All" OnClick="AttendAllButton_Click" />

          </td> 
          </table>
        </FooterTemplate>
      </asp:Repeater>
      <!-- end parent repeater -->
    </div>
  </form>
</body>
</html>
 

Вот моя загрузка страницы и код привязки:

   Public Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
 
    bindData()
    If Not IsPostBack Then ' Do this for first time page loads
      familyRepeater.DataSource = Session("Families")
      familyRepeater.DataBind()
    End If
  End Sub

  Private Sub bindData()
    'test data
    Dim RptYrMo As String = "202007"
    Dim agency As Integer = 879
    Dim subAgencyCode As String = "000"

    Dim familiesDataSet As DataSet = New DataSet()

    ' Fill data tables for families, children, and settings
    dtFamilies = Attendance.GetFamilies(RptYrMo, agency, subAgencyCode)
    dtChildren = Attendance.GetChildren(RptYrMo, agency, subAgencyCode)

    'Add data tables to data set
    familiesDataSet.Tables.Add(dtFamilies)
    familiesDataSet.Tables.Add(dtChildren)
    'Add relationship
    familiesDataSet.Relations.Add("FamilyChildRelation", familiesDataSet.Tables("Families").Columns("FamilyID"), familiesDataSet.Tables("Children").Columns("FamilyID"))

    'Bind the data set
    familyRepeater.DataSource = familiesDataSet.Tables("Families")
    familyRepeater.DataBind()

    Session("Families") = familiesDataSet.Tables("Families")

  End Sub
 

Спасибо за ваше время.

Комментарии:

1. Вы вызываете familyRepeater.DataBind() , а затем начинаете искать дочерний повторитель. Если вы создаете его динамически, вам необходимо воссоздавать его при каждой загрузке страницы (включая обратную отправку) или после вызова DataBind на родительском сервере.

2. @VDWWD Я действительно звонил familyRepeater.DataBind() в начале этого события.

3. Я добавил больше своего кода в свой исходный пост

4. Page_Load слишком поздно в жизненном цикле для привязки данных. Любые события на внутреннем повторителе не будут запускаться, потому что он еще не будет существовать в той части жизненного цикла страницы, которая объединяет события.

Ответ №1:

Я нашел ответ. Мне пришлось изменить эту строку:

Dim childRepeater As Repeater = TryCast(item.FindControl("childRepeater"), Repeater)

для этого:

Dim childRepeater As WebControls.Repeater = TryCast(item.FindControl("childRepeater"), WebControls.Repeater)

Ответ №2:

Я бы изменил весь подход здесь. Вместо того, чтобы пытаться обновить элементы управления, я бы обновил источник данных, а затем снова вызвал bindData(), чтобы элементы управления были построены из этих новых данных, какими они должны быть.