繁体   English   中英

从基本页面访问子页面控件

[英]Access child page controls from base page

在我的ASP.NET应用程序内部,我所有的Web内容页面都派生自基类,而基类派生自System.Web.UI.Page。 在此基类内部,我需要在一个派生类SamplePage.aspx:BaseClass.cs中找到一些控件。 我在SamplePage.aspx中的页面加载下面添加了C#代码,它找到了ContentPlaceHolderControl,

<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder> /* defined in the master page */

/* inside SamplePage.aspx */
<ajaxtoolkit:tabcontainer runat="server" id="tabsmain" height="405px" Width="625px">
ContentPlaceHolder cph = (ContentPlaceHolder)this.Master.FindControl("ContentPlaceHolder1");
AjaxControlToolkit.TabContainer container = (AjaxControlToolkit.TabContainer)cph.FindControl("tabsmain");

而如果我将其添加到基类中,则会出现此错误:

内容控件必须是内容页或引用母版页的嵌套母版页中的顶级控件。

有没有办法我也可以在基类中获取ContentPlaceHolder? 而我该如何访问呢?

以下是完整的示例代码,您可以通过它们访问ContentPlaceHolder:

第一个主代码(Site1.master):

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site1.master.cs" Inherits="WebTesterInherit.Site1" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">

        </asp:ContentPlaceHolder>
    </div>
    </form>
</body>
</html>

现在,自类继承自Page:

public class MyPage: System.Web.UI.Page
{

    public System.Web.UI.WebControls.ContentPlaceHolder GetMyContentPlaceHolder()
    {
        System.Web.UI.WebControls.ContentPlaceHolder holder = null;
        Site1 site = this.Master as Site1;
        if (site != null)
        {
            holder = site.FindControl("ContentPlaceHolder1") as System.Web.UI.WebControls.ContentPlaceHolder;
        }
        return holder;
    }
}

最后是从MyPage(Default.aspx)继承的页面:

<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebTesterInherit.Default" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <asp:Button ID="btnTest" runat="server" Text="Test" OnClick="btnTest_Click"/><br />
    <asp:Label ID="lblMessage" runat="server" Text=""></asp:Label>
</asp:Content>

Default.aspx的代码:

public partial class Default : MyPage
{
    protected void Page_Load(object sender, EventArgs e)
    {

    }

    protected void btnTest_Click(object sender, EventArgs e)
    {
        try
        {
            System.Web.UI.WebControls.ContentPlaceHolder holder = base.GetMyContentPlaceHolder();
            lblMessage.Text = string.Format("Holder contains {0} control(s).", holder.Controls.Count);
        }
        catch (Exception ex)
        {
            lblMessage.Text = string.Format("Error: {0}", ex.Message);
        }
    }
}

经过检查,您可以从基类OnLoad方法中找到嵌套在ContentPlaceHolder的控件。

当然可以。。 但是请记住,某些页面的CPH中可能有不同的控件。 您确定您位于实际上具有tabsmain控件的页面的上下文中吗?

我认为,如果必须执行此类操作,则会遇到一些设计问题。 母版页和向下的FindControl (基类->派生类)的混合感觉并不正确。

通用的“按ID和类型搜索”方法:

  protected T GetControlOfType<T>(Control root, string id) where T : Control {
    var stack = new Stack<Control>();
    stack.Push(root);
    while (stack.Count > 0) {
      var control = stack.Pop();
      var typedControl = control as T;
      if (typedControl != null && string.Compare(id, typedControl.ID, StringComparison.Ordinal) == 0) {
        return typedControl;
      }
      foreach (Control child in control.Controls) {
        stack.Push(child);
      }
    }
    return default(T);
  }

用法:

   var control = GetControlOfType<MyControl>(Page, "MyControlServerID");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM