C# ASP.NET如何访问父页上的深度嵌套用户控件

C# ASP.NET如何访问父页上的深度嵌套用户控件,c#,asp.net,user-controls,findcontrol,C#,Asp.net,User Controls,Findcontrol,我有一个login控件,at嵌套在头控件的2深处 i、 电子页面->标题控制->登录控制。我无法使用FindControl获取对页面上控件的引用。我希望能够设置控件的visible属性,如 if (_loginControl != null) _loginControl.Visible = false; 我最终使用递归FindControl方法来查找嵌套控件 public static Control FindControlRecursive(Control

我有一个login控件,at嵌套在头控件的2深处 i、 电子页面->标题控制->登录控制。我无法使用FindControl获取对页面上控件的引用。我希望能够设置控件的visible属性,如

  if (_loginControl != null)
            _loginControl.Visible = false;
我最终使用递归FindControl方法来查找嵌套控件

    public static Control FindControlRecursive(Control root, string id)
    {
        if (root.ID == id)
        {
            return root;
        }

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

        return null;
    }

一个好方法是使用:

Page.FindControl() 

如果结果为null,则该控件不存在。

尝试调用this.FindControl\u loginControl或this.Page.FindControl\u loginControl

有关方法的详细信息,请参见MSDN:

您是否需要在ASP.NET页面上禁用/隐藏用户控件,或者用户控件是否存在于母版页上?如果它位于同一页面中,则在ASP.NET页面的代码中,您可以执行以下操作:

MyUserControlsID.Visible = false
其中MyUserControl是用户控件的ID。要确定用户控件的ID,请查看.aspx页面的标记,您将看到如下内容:

<uc1:UserControlName ID="MyUserControlsID" runat="server" ... />

快乐编程

登录控件如果在标记中注册,也将是codebehind页面的实例成员;您可以从codebehind类中引用它,就像它是一个普通成员一样,使用您提供的ID相同的名称。我建议对大多数逻辑使用codebehinds,而不是在标记中内联代码,顺便说一句

您还可以使用页面的FindControl方法,该方法将在其控件子树中搜索具有给定ID的控件。这需要更长的时间,因此我建议使用第一个选项,除非动态添加逻辑控件,并且您并不总是知道它在那里

private List<Control> GetAllNestedUserControl(Control ph)
    {
        List<Control> Get = new List<Control>();
        foreach (var control in ph.Controls)
        {
            if (control is UserControl)
            {
                UserControl uc = control as UserControl;
                if (uc.HasControls())
                {
                   Get =  GetAllNestedUserControl(uc);

                }
            }
            else
            {
                Control c = (Control)control;
                if (!(control is LiteralControl))
                {
                     Get.Add(c);
                }
            }
        }
        return Get;
    }
只需从任何父页面调用此代码,然后通过以下代码获得任何控件

        List<Control> Get = GetAllNestedUserControl(ph);
        Label l = (Label)Get.Find(o => o.ID == "lblusername");
        l.Text = "changed from master";

我不知道你说的测试是否存在是什么意思?是否将其动态添加到页面?如果您在标记中声明了它,那么它必须有一个ID和runat=server,这样您就可以通过ID引用它,并且应该始终填充它。是的,但是FindControl将ID作为字符串。用户控件的ID是什么?这里有很多警告。FindControl不是递归的。如果控件嵌套得很深,这将不起作用。此外,只有在控件是动态添加的情况下,他们才需要这样做。用户控件的ID是通过“属性”窗口或.aspx页面中的声明性标记设置的ID。就像文本框或按钮有一个ID一样,用户控件也有一个ID。因此,如果其嵌套的2个控件很深,我应该将其强制转换为控件类型吗?@Zener:你可以这样做。您还可以创建一个递归FindControl方法——已经有很多了。这里有一个-感谢Scott,我使用的是FindControl,但没有使用声明性代码中的正确ID。这里的每个人都是对的,谢谢。我会记住注意事项Josh。如果用户控件位于ASP.NET页面本身,则不需要使用FindControl。您应该能够像引用任何其他Web控件一样从代码隐藏类引用它,例如:MyUserControlsID。实际上,它是页面上控件中的一个控件,因此它的ID在ascx中。我确实需要使用FindControl。或者,您可以使用父用户控件的公共属性显示该控件,这意味着您可以从ASP.NET页面的代码隐藏类中执行以下操作:ParentUserControl.ChildUserControl。但无论如何,我很高兴你找到了解决办法-