地球人都知道asp.net页面加了MasterPage后会改变原来页面控件的ID.也隐约知道ID好像是一层一层父子关系嵌套下来的.但实际上真是这样吗?
今天我们就来试试实际会怎么样: (页面已经加MasterPage)
<div id="div1" runat="server">
<table id="table1" runat="server">
<tr id="tr1" runat="server">
<td id="td1" runat="server">
<asp:Label ID="lbl1" runat="server" Text="aa"></asp:Label></td>
<td id="td2">
<asp:Label ID="lbl2" runat="server" Text="bb"></asp:Label></td>
</tr>
</table>
</div>
产生的源代码如下:
<div>
<div id="ctl00_ContentPlaceHolder1_div1">
<table id="ctl00_ContentPlaceHolder1_table1">
<tr id="ctl00_ContentPlaceHolder1_tr1">
<td id="ctl00_ContentPlaceHolder1_td1">
<span id="ctl00_ContentPlaceHolder1_lbl1">aa</span></td>
<td id="ctl00_ContentPlaceHolder1_td2">
<span id="ctl00_ContentPlaceHolder1_lbl2">bb</span></td>
</tr>
</table>
</div>
</div>
可以看出所有控件都加上了"ctl00_ContentPlaceHolder1_",这个就是MasterPage的影响了.但是,这个好像没有我们印象中的层层包围哦!
我们再改一下代码,改成如下:
<div id="div1" runat="server">
<table id="table2" runat="server">
<tr id="tr2" runat="server">
<td id="td3" runat="server">
<asp:Repeater ID="rpt1" runat="server">
<ItemTemplate>
<asp:Label ID="lbl3" runat="server" Text="aa"></asp:Label>
</ItemTemplate>
</asp:Repeater>
</td>
</tr>
</table>
</div>
在Page_load中加入:
string[] str = new string[] { "aa", "bb" };
rpt1.DataSource = str;
rpt1.DataBind();
运行结果如下:
<div>
<div id="ctl00_ContentPlaceHolder1_div1">
<table id="ctl00_ContentPlaceHolder1_table2">
<tr id="ctl00_ContentPlaceHolder1_tr2">
<td id="ctl00_ContentPlaceHolder1_td3">
<span id="ctl00_ContentPlaceHolder1_rpt1_ctl00_lbl3">aa</span>
<span id="ctl00_ContentPlaceHolder1_rpt1_ctl01_lbl3">aa</span>
</td>
</tr>
</table>
</div>
</div>
终于看到我们想要的结果了! Lable生成的<span> Id有嵌套Repter的Id了! ("太弱智了吧,这样也要试??" ~~好像听到很多嘘声-_-||)
既然大家都说太弱智了就不再研究了.总结一下:
1. 加MasterPage都会在Id前面加入类似"ctl00_ContentPlaceHolder1_"的前缀.无论多少层,都只加一个.
2.如果页面中存在重复控件(重复控件包括 Repeater、DataList 和 DataGridWeb 服务器控件(或任何在数据绑定时创建的包含重复功能的自定义服务器控件),它们充当其子控件的命名容器)的话,重复控件内部的控件Id前缀将加上重复控件Id一起作为改控件前缀,避免重复.
另外,在后台动态添加控件的话,如果你要取ClientID或者UniqueID的话..就要注意了.
string id = string.Empty;
Table ht = new Table();
ht.ID = "table1";
TableRow tr = new TableRow();
tr.ID = "row1";
TableCell tc = new TableCell();
tc.ID = "cell1";
id = string.Format("<br /> Table Id:{0} <br /> Row Id:{1} <br /> Cell Id:{2}", ht.ClientID, tr.ClientID, tc.ClientID);
this.div1.Controls.Add(ht);
ht.Rows.Add(tr);
id += string.Format("<br /> Table Id:{0} <br /> Row Id:{1} <br /> Cell Id:{2}", ht.ClientID, tr.ClientID, tc.ClientID);
tr.Cells.Add(tc);
this.lbl1.Text = id;
上边的代码,你想想会出现什么结果? 先自己想想...
实际显示输出如下:
Table Id:table1
Row Id:row1
Cell Id:cell1
Table Id:ctl00_ContentPlaceHolder1_table1
Row Id:ctl00_ContentPlaceHolder1_row1
Cell Id:cell1
但是页面HTML源代码是:
<div>
<div id="ctl00_ContentPlaceHolder1_div1">
<span id="ctl00_ContentPlaceHolder1_lbl1"><br /> Table Id:table1 <br /> Row Id:row1 <br /> Cell Id:cell1<br /><br /> Table Id:ctl00_ContentPlaceHolder1_table1 <br /> Row Id:ctl00_ContentPlaceHolder1_row1 <br /> Cell Id:cell1</span>
<table id="ctl00_ContentPlaceHolder1_table1" border="0">
<tr id="ctl00_ContentPlaceHolder1_row1">
<td id="ctl00_ContentPlaceHolder1_cell1"></td>
</tr>
</table></div>
</div>
可以看出ClientID和UniqueID都必须Add到最终的页面Control了之后,才能正确取到页面最终的ID.
这个试验也很弱智吧-_-||,,,做这个试验是因为今天和一同事争论到底控件ID是什么时候加载前缀的.是在Add之前还是之后..囧..码完字,闪了~~