Page.FindControl(string id) 与母版页结合后发现的一个问题

MSDN上解释Page.FindControl(string id)方法用于查找指定ID的控件。例如:

<asp:TextBox id="Email" runat="server"></asp:TextBox>

TextBox txt = this.Page.FindControl("Email") as TextBox;
txt.Text = "abc@163.com";

 该方法有点类似javascript中的getElementById(string)。但实际上,经过试验发现id这个参数并不是TextBox控件的ID,而是TextBox控件生成HTML代码后的name属性。如下代码:

 <asp:TextBox id="TextBox1" runat="server"></asp:TextBox>

其生成的HTML代码为:

<input name="TextBox1" type="text" id="TextBox1" />

我们看到,在默认情况下,控件TextBox的id属性对应生成后的input标签的id属性和name属性(id == name)。当有母版页存在的时候,情况就变得不一样了。当出现如下模板页时:

<asp:ContentPlaceHolder ID="BodyContent" runat="server"></asp:ContentPlaceHolder>
<asp:TextBox id="RealName" runat="server"></asp:TextBox>

生成的HTML变为了:<input name="ctl00$BodyContent$RealName" type="text" id="BodyContent_RealName" />

此时我们使用this.Page.FindControl("RealName"),系统会返回null。我们逐一尝试,this.Page.FindControl("BodyContent_RealName"),系统仍旧返回null。this.Page.FindControl("ctl00$BodyContent$RealName"),OK,正常了,天下太平了。

通过以上调试过程,我们发现Page.FindControl(string id)方法的id参数实质上是控件生成HTML代码后的name属性。默认情况下(没有模板页时),控件的ID属性会同时赋值给控件生成的对应html的标签的name和id属性。所以,此时Page.FindControl(string id)方法的id参数只要输入控件的ID属性即可。否则则需要输入控件生成HTML标签后的name属性。

通过如上代码,我们还发现在使用模板页时,控件的生成HTML标签后,对应的ID属性也变了,由"RealName"变为了"BodyContent_RealName"(模板页对应区域的ID+"_"+控件原来的ID)。无疑,这种ID不是很友好,给模板页的ContentPlaceHolder控件增加ClientIDMode="Static"属性后,可以解决这一问题:

<asp:ContentPlaceHolder ID="BodyContent" ClientIDMode="Static" runat="server"></asp:ContentPlaceHolder>
<asp:TextBox id="RealName" runat="server"></asp:TextBox>
<input name="ctl00$BodyContent$RealName" type="text" id="RealName">

 我们发现,增加如上属性后,生成的HTML标签中,id属性保持了不变,但是name属性仍旧不太友好,聊胜于无吧,毕竟大多数时候我们使用js时都是使用getElementById(string)而不是使用getElementByTagName(string)

原文地址:https://www.cnblogs.com/cnuusw/p/3515414.html