回顾一下这种情况-您需要从子控件对页面上的控件执行 FindControl,但是-
- 您的项目有一个 MasterPage,在这种情况下
this.Page
似乎不起作用,我们this.Parent
改用
- 您的“目标”控件位于 PlaceHolder 内部,而 PlaceHolder 本身位于 ContentPlaceHolder 内部,因此它并不像刚才那样简单
this.Parent.FindControl()
- 试图查找“目标”控件的子 ASCX 控件(在本例中为文本框)实际上位于另一个 ContentPlaceHolder 中,因此 this.Parent.Parent 或其他任何内容都不起作用。
由于您在我最初this.Parent
的回答之后提到控件彼此位于不同的 ContentPlaceHolder 中,并且在另一个子控件中,因此您的查询有点复杂。
基于这些标准,以及您至少知道包含(其中某处)您的目标 TextBox 的 contentPlaceHolder 控件这一事实,下面是我编写的一些代码,适用于新的 ASP.net Web 窗体应用程序:
它递归地检查您传递给它的 ContentPlaceHolder 的控件集合,并找到您的控件。
只需传递 ControlID 和 ContentPlaceHolderID,它就会递归地找到它。
这段代码用相同的项目替换了我下面的原始代码,位于 ChildControl.ascx.cs 文件内:
使用系统;使用 System.Web.UI;使用 System.Web.UI.WebControls;使用 System.Linq;使用 System.Collections.Generic;
namespace FindControlTest
{
public partial class ChildControl : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
var textBoxTest = FindControlInContentPlaceHolder("TextBoxTest", "FeaturedContent") as TextBox;
Response.Write(textBoxTest.Text);
Response.End();
}
private Control FindControlInContentPlaceHolder(string controlID, string contentPlaceHolderID)
{
if (null == this.Page ||
null == this.Page.Master)
{
return null;
}
var contentPlaceHolder = this.Page.Master.FindControl(contentPlaceHolderID);
var control = getChildControl(controlID, contentPlaceHolder);
return control;
}
private Control getChildControl(string controlID, Control currentControl)
{
if (currentControl.HasControls())
{
foreach(Control childControl in currentControl.Controls)
{
var foundControl = childControl.FindControl(controlID);
if (null != foundControl)
{
return foundControl;
}
else
{
return getChildControl(controlID, childControl);
}
}
}
return null;
}
}
}
笔记:
我在一些事件中尝试了这个,甚至在 Init() 上我也能够获得 TextBox 值如果您看到 null,则可能是由于传递了不正确的 ID 或我尚未遇到的情况。如果您使用附加信息编辑您的问题(因为已经有很多信息)并显示什么变量为空,则可以解决。
请注意,我在 MasterPage 中添加了一些复杂性,例如 Panel 中的 PlaceHolder,然后将 ContentPlaceHolder 放在那里,代码仍然有效。我什至为 .net 4.5、4.0、3.5 和 3.0 进行了编译,我认为 FindControl 与 MasterPages 的工作方式可能不同,但它仍然每次都能工作。如果您仍然得到空值,您可能需要发布一些额外的标记。
测试项目的其余部分
页面(基于默认 MasterPage)
<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FindControlTest._Default" %>
<%@ Register TagName="ChildControl" TagPrefix="uc1" Src="~/ChildControl.ascx" %>
<asp:Content runat="server" ContentPlaceHolderID="FeaturedContent">
<asp:PlaceHolder ID="PlaceHolderTest" runat="server">
<asp:TextBox ID="TextBoxTest" Text="Hello!" runat="server"/>
</asp:PlaceHolder>
</asp:Content>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<uc1:ChildControl id="ChildControlTest" runat="server" />
</asp:Content>
我添加了一个名为 ChildControl.ascx 的控件,其中只有这个:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ChildControl.ascx.cs" Inherits="FindControlTest.ChildControl" %>
Hello child!
结果是“你好!” 在页面上。