我有一个ASP.NET Web窗体页childPage.aspx
,其中masterPage.aspx
作为母版页。 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
是id
上<div runat="server" />
的childPage.aspx
。现在,我正在尝试从用户控件中访问它,但这无法返回div
。
请帮帮我。我应该怎么做?预先感谢。
之所以不起作用,可能是因为FindControl()
方法不是递归。这在MSDN documentation中被调用:
仅当控件直接包含在指定的容器中时,此方法才会找到控件;也就是说,该方法不会在控件内的整个控件层次结构中进行搜索。
例如,Page.FindControls()
将仅搜索Page.Controls
集合中列出的控件;它不会搜索每个those控件的Controls
集合。因此,Page.FindControl()
仅在ProductMenu
位于ASPX页面的top-level时才有效;如果例如嵌套在Panel
控件中,则此代码将无效。
要解决此问题,您需要编写一个递归函数以对控件树进行爬网。例如:
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;
}
在您的情况下,假设您将[[总是正在寻找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
类,以便可以在多个页面上轻松访问它。