Asp.net FindControl()返回null

Asp.net FindControl()返回null,asp.net,findcontrol,dynamically-generated,Asp.net,Findcontrol,Dynamically Generated,我正在尝试创建应用程序whad add controlls dynamicali。我有母版页,我的asp:内容如下: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <asp:ScriptManager ID="scriptManager1" runat="server"> </asp:ScriptManager> <div style="m

我正在尝试创建应用程序whad add controlls dynamicali。我有母版页,我的asp:内容如下:

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<asp:ScriptManager ID="scriptManager1" runat="server">
</asp:ScriptManager>   
<div style="margin: 10px">
    <asp:UpdatePanel ID="updatePanel1" runat="server">
        <ContentTemplate>
            <asp:PlaceHolder runat="server" ID="myPlaceHolder" />
        </ContentTemplate>
        <Triggers>
            <asp:AsyncPostBackTrigger ControlID="btnAdd" EventName="Click" />
        </Triggers>
    </asp:UpdatePanel>
</div>
<asp:Button ID="btnAdd" runat="server" Text="Add" />

这是我的代码:

    static int myCount = 1;
    private TextBox[] color;
    private TextBox[] text;

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        color = new TextBox[myCount];
        text = new TextBox[myCount];

        for (int i = 0; i < myCount; i++)
        {
            TextBox tbColor = new TextBox();
            tbColor.ID = "colorTextBox" + i.ToString();
            myPlaceHolder.Controls.Add(tbColor);
            color[i] = tbColor;

            TextBox tbText = new TextBox();
            tbText.ID = "textTextBox" + i.ToString();
            myPlaceHolder.Controls.Add(tbText);
            text[i] = tbText;

            LiteralControl literalBreak = new LiteralControl("<br />");
            myPlaceHolder.Controls.Add(literalBreak);
        }
    }


    public Control GetPostBackControl(Page page)
    {
        Control control = null;
        string ctrlname = page.Request.Params.Get("__EVENTTARGET");
        if (ctrlname != null && ctrlname != string.Empty)
        {
            control = page.FindControl(ctrlname);
        }
        else
        {
            foreach (string ctl in page.Request.Form)
            {
                Control mycontrol = page.FindControl(ctl);
                if (mycontrol is System.Web.UI.WebControls.Button)
                {
                    control = mycontrol;
                    // This gives you ID of which button caused postback                        
                    break;
                }
            }
        }
        return control;
    }

    protected void Page_PreInit(object sender, EventArgs e)
    {
        Control myControl = GetPostBackControl(this.Page);
        if (myControl != null)
            if (myControl.ClientID.ToString() == "btnAdd")
                myCount = myCount + 1;
    }

    protected void btnAdd_Click(object sender, EventArgs e)
    {
        //handled in PreInit    

    }
static int myCount=1;
私有文本框[]颜色;
私有文本框[]文本;
受保护的覆盖无效OnInit(事件参数e)
{
碱基.奥尼特(e);
颜色=新文本框[myCount];
text=新文本框[myCount];
for(int i=0;i”);
myPlaceHolder.Controls.Add(literalBreak);
}
}
公共控件GetPostBackControl(第页)
{
控制=空;
string ctrlname=page.Request.Params.Get(“\uu EVENTTARGET”);
if(ctrlname!=null&&ctrlname!=string.Empty)
{
控件=page.FindControl(ctrlname);
}
其他的
{
foreach(page.Request.Form中的字符串ctl)
{
Control mycontrol=page.FindControl(ctl);
if(mycontrol是System.Web.UI.WebControls.Button)
{
控制=mycontrol;
//这将为您提供导致回发的按钮的ID
打破
}
}
}
返回控制;
}
受保护的无效页\u PreInit(对象发送方,事件参数e)
{
Control myControl=GetPostBackControl(this.Page);
if(myControl!=null)
if(myControl.ClientID.ToString()=“btnAdd”)
myCount=myCount+1;
}
受保护的无效btnAdd_单击(对象发送者,事件参数e)
{
//在PreInit中处理
}

在loap foreach中的函数GetPostBackControl()中查找我的btnAdd时,例如在ctr“ctl00$MainContent$scriptManager1”的第一次迭代中,myControl为null。。。在下一个迭代中也。。。所以我的函数总是返回null。原因是什么?

FindControl
仅搜索容器的直接子级。由于您是从页面级别开始的,因此需要通过子
UpdatePanel
控件递归到
btnAdd
控件

请看一个如何执行此操作的示例

编辑: 我不确定我是否理解您为什么以这种方式“寻找”按钮,因为屏幕上只有一个静态按钮-在这种情况下,您不需要使用
FindControl

<asp:Button ID="btnAdd" runat="server" Text="Add" onclick="btnAdd_Click" />
如果您希望已添加的所有控件在回发之间“保留”,请在页面和控件上启用viewstate,然后确保在OnInit中只添加一次控件而不回发:

   base.OnInit(e);    
   if (!IsPostBack)
   { // ... Add controls here

您可以将“mycount”的状态保留在一个隐藏字段中(在相同的updatepanel中,并且启用了viewstate)——每次都需要将其解析为int。或者您可以使用SessionState来跟踪它。

谢谢您的回答!稍后我会在这里添加第二个静态按钮,动态地只会在这里添加文本框。那么你认为我可以用这里的btnAdd_Click()?我不知道,如何在按钮中增加myCount,然后在myCount上用新值重新加载页面。你觉得怎么样?
   base.OnInit(e);    
   if (!IsPostBack)
   { // ... Add controls here