これは、同じ FindControl コードがポストバックではないときにコントロールを見つけるため、私を困惑させました。これが状況です。
カスタム コントロール (ClassCell.ascx) があります。これには、特定の役割を持つユーザーのみのリンクを表示する LoginView があります。
...
<asp:LoginView ID="LoginView1" runat="server">
<RoleGroups>
<asp:RoleGroup Roles="Instructor">
<ContentTemplate>
<a id="btnEdit" class="cssButtonPink" runat="server" href="">Edit</a>
</ContentTemplate>
</asp:RoleGroup>
</RoleGroups>
</asp:LoginView>
...
したがって、リンクは「btnEdit」と呼ばれます。
カスタム コントロールには SetClass というメソッドがあり、FindControl を使用して 'btnEdit' コントロールを見つけ、その href が指すものを設定します。
Public Sub SetClass
...
Dim editButton As HtmlAnchor = Me.LoginView1.FindControl("btnEdit")
If editButton IsNot Nothing Then
editButton.HRef = "~/Instructors/ManageClasses.aspx?c=" + ClassID.ToString
End If
...
End Sub
Signup.aspx ページの PreRender 段階でカスタム コントロールを動的に追加し、その直後にその SetClass メソッドを呼び出しています。
Private Sub ClassSignup_PreRender(sender As Object, e As System.EventArgs) Handles Me.PreRender
...
If IsPostBack Then
...
Else
...
End If
...
' this is where my misbehaving control is (indirectly) created '
Dim cc As New ClassCell
cc = LoadControl("~\Members\ClassCell.ascx")
cc.SetClass(objClass)
...
End Sub
なぜ間接的に?ネストされたカスタム コントロールがいくつかあるため、実際にはもう少し複雑です。しかし、すべてのアクションは、私が示した PreRender で行われます。RoomTable カスタム コントロールを作成します。その中に ScheduleRow カスタム コントロールが作成され、CellClass コントロールが作成されるのは ScheduleRow のメソッド内です。この入れ子が重要かどうかはわかりません。
postBack でない場合、これは最初のページ読み込みで完全に機能します。ただし、メイン ページには、次の週または前の週に進むことができるボタンもあります。ここでポストバックの出番です。ポストバックで上記のコードを実行すると、FindControl が Nothing を返すことがわかります。また、LoginView1.Controls.Count = 0 であることもわかります。そのため、コントロールの階層を再帰するだけの問題ではないようです。ポストバックにコントロールがない理由がわかりません。
さらに奇妙なことに、「編集ボタン」は実際にレンダリングされますが、コントロールが見つからなかったため、コードで設定に失敗したため、ハイパーリンクはアクティブではありません。つまり、それはタイミングの問題のようで、操作しようとしているときにコントロールが存在せず、後で制御できるようになります。PreRender はこれをやろうとするのは間違った時期ですか?
助けてくれてありがとう。シンプルなものが欠けていることを願っています。サンドラ