0

在我的 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 ?我怎样才能访问它?

4

3 回答 3

0

Universal "search by id and type" method:

  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);
  }

Usage:

   var control = GetControlOfType<MyControl>(Page, "MyControlServerID");
于 2013-06-07T11:31:59.680 回答
0

以下是如何访问 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);
        }
    }
}
于 2013-06-07T11:13:34.133 回答
0

我已经检查过了,你可以找到一个嵌套在ContentPlaceHolder基类OnLoad方法中的控件。

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

我认为如果你必须做这样的事情你有一些设计问题。母版页和向下FindControl(基类 -> 派生类)的混合感觉不对。

于 2013-06-07T11:17:34.713 回答