在嵌套母版页中查找控件

use*_*885 8 c# asp.net master-pages .net-3.5

我有一个嵌套2级的母版页.它有一个母版页,该母版页有一个母版页.

当我在名为"bcr"的ContentPlaceHolder中粘贴控件时 - 我必须找到如下所示的控件:

 Label lblName =(Label)Master.Master.FindControl("bcr").FindControl("bcr").FindControl("Conditional1").FindControl("ctl03").FindControl("lblName");
Run Code Online (Sandbox Code Playgroud)

我完全失去了吗?或者这是它需要做的?

我即将使用MultiView,它位于条件内容控件中.所以,如果我想要更改视图,我必须获得对该控件的引用吗?得到这个参考将更加肮脏!有没有更好的办法?

谢谢

Mun*_*Mun 23

找到控件是一件痛苦的事情,我一直在使用这种方法,这是我很久以前从CodingHorror博客中获得的,只有一个修改,如果传入一个空id,则返回null.

/// <summary>
/// Recursive FindControl method, to search a control and all child
/// controls for a control with the specified ID.
/// </summary>
/// <returns>Control if found or null</returns>
public static Control FindControlRecursive(Control root, string id)
{
    if (id == string.Empty)
        return null;

    if (root.ID == id)
        return root;

    foreach (Control c in root.Controls)
    {
        Control t = FindControlRecursive(c, id);
        if (t != null)
        {
            return t;
        }
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

在您的情况下,我认为您需要以下内容:

Label lblName = (Label) FindControlRecursive(Page, "lblName");
Run Code Online (Sandbox Code Playgroud)

使用此方法通常更方便,因为您不需要确切知道控件所在的位置(当然,假设您知道ID),但如果您使用相同名称的嵌套控件,则会可能会有一些奇怪的行为,所以这可能需要注意.


and*_*ndy 4

首先,您应该知道 MasterPages 实际上位于 Pages 内部。以至于 MasterPage 的 Load 事件实际上是在 ASPX 的 Load 事件之后调用的。

这意味着,Page 对象实际上是控件层次结构中的最高控件。

因此,了解这一点后,在此类嵌套环境中查找任何控件的最佳方法是编写一个递归函数,循环遍历每个控件和子控件,直到找到您要查找的控件。在这种情况下,您的 MasterPage 实际上是主 Page 控件的子控件。

您可以从任何控件内部访问主 Page 对象,如下所示:

C#:

这一页;

网络

我的佩奇

我发现通常情况下,Control 类的 FindControl() 方法非常无用,因为环境总是嵌套的。

因为如果是这样,我决定使用.NET 3.5 的新扩展功能来扩展 Control 类。

通过使用下面的代码 (VB.NET),在您的 AppCode 文件夹中,您的所有控件现在将通过调用 FindByControlID() 执行递归查找

    Public Module ControlExtensions
    <System.Runtime.CompilerServices.Extension()> _
    Public Function FindControlByID(ByRef SourceControl As Control, ByRef ControlID As String) As Control
        If Not String.IsNullOrEmpty(ControlID) Then
            Return FindControlHelper(Of Control)(SourceControl.Controls, ControlID)
        Else
            Return Nothing
        End If
    End Function

    Private Function FindControlHelper(Of GenericControlType)(ByVal ConCol As ControlCollection, ByRef ControlID As String) As Control
        Dim RetControl As Control

        For Each Con As Control In ConCol
            If ControlID IsNot Nothing Then
                If Con.ID = ControlID Then
                    Return Con
                End If
            Else
                If TypeOf Con Is GenericControlType Then
                    Return Con
                End If
            End If

            If Con.HasControls Then
                If ControlID IsNot Nothing Then
                    RetControl = FindControlByID(Con, ControlID)
                Else
                    RetControl = FindControlByType(Of GenericControlType)(Con)
                End If

                If RetControl IsNot Nothing Then
                    Return RetControl
                End If
            End If
        Next

        Return Nothing
    End Function

End Module
Run Code Online (Sandbox Code Playgroud)