1

childPage.aspx我有一个masterPage.aspx作为母版页的 ASP.NET Web 表单页面。其childPage.aspx上定义了一个用户控件 ( userControl.ascx) 控件。现在,我正在尝试childPage.aspx从用户控件中访问控件。我尝试了几种不同的方法:

HtmlContainerControl ProductMenu = (HtmlContainerControl)Page.FindControl("ProductMenu");

HtmlContainerControl ProductMenu = (HtmlContainerControl)this.Page.FindControl("ProductMenu");

HtmlContainerControl ProductMenu = (HtmlContainerControl)Parent.FindControl("ProductMenu");

HtmlContainerControl ProductMenu = (HtmlContainerControl)this.Parent.parent.FindControl("ContaintHolder").FindControl("ProductMenu")

在上面的代码中,ProductMenu是onid的。现在,我正在尝试从我的用户控件中访问它,但是无法返回.<div runat="server" />childPage.aspxdiv

请帮帮我。我该怎么做?提前致谢。

4

1 回答 1

1

这不起作用的原因可能是因为该FindControl()方法不是递归的。这在MSDN 文档中被调用:

只有当控件直接包含在指定容器中时,此方法才会找到控件;也就是说,该方法不会在控件内的控件层次结构中进行搜索。

因此,例如,Page.FindControls()搜索Page.Controls集合中列出的控件;它不会搜索每个控件Controls集合。因此,仅当 位于您的 ASPX 页面的顶层时才有效;如果它嵌套在例如控件中,则此代码将不起作用。Page.FindControl()ProductMenuPanel

要解决此问题,您需要编写一个递归函数来爬取控制树。例如:

public Control FindControl(Control parentControl, string controlName) {
  foreach (var childControl in parentControl.Controls) {
    if (childControl.Id == controlName) return childControl;
    var foundControl = FindControl(childControl, controlName);
    if (foundControl != null) return childControl;
  }
  return null;
}

在您的情况下,假设您总是在寻找 an 的实例HtmlContainerControl,您甚至可以验证类型并返回一个强类型对象,如果您选择的话。也就是说,如果你想保持它的强类型同时仍然支持不同的类型,你可以改用泛型:

public T FindControl<T>(Control parentControl, string controlName) where T : Control {
  foreach (var childControl in parentControl.Controls) {
    if (childControl.Id == controlName) return childControl;
    var foundControl = FindControl<T>(childControl, controlName);
    if (foundControl != null && foundControl is T) return childControl;
  }
  return null;
}

此外,如果您需要重复执行此操作,您可以将其作为扩展方法添加到Page类中,以便在多个页面上轻松访问它。

于 2015-06-07T21:46:49.017 回答