簡體   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