[英]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.