如何从 ASP.NET 用户控件中从父页访问控件

本文关键字:控件 访问 用户 ASP NET | 更新日期: 2023-09-27 18:37:20

我有一个 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")

在上面的代码中,ProductMenuchildPage.aspx<div runat="server" />id。现在,我正在尝试从我的用户控制范围内访问它,但这无法返回div

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

如何从 ASP.NET 用户控件中从父页访问控件

这不起作用的原因可能是因为FindControl()方法不是递归的。MSDN 文档中对此进行了说明:

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

因此,例如,Page.FindControls()将仅搜索Page.Controls集合中列出的控件;它不会搜索每个控件的Controls集合。因此,仅当ProductMenu位于 ASPX 页的顶层时,Page.FindControl()才会起作用;例如,如果它嵌套在 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 类中,以便在多个页面上轻松访问它。