关于控件ID的试验(涉及MasterPage)

地球人都知道asp.net页面加了MasterPage后会改变原来页面控件的ID.也隐约知道ID好像是一层一层父子关系嵌套下来的.但实际上真是这样吗?

今天我们就来试试实际会怎么样: (页面已经加MasterPage)

Html1
    <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>

产生的源代码如下:

Code1
    <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的影响了.但是,这个好像没有我们印象中的层层包围哦!

我们再改一下代码,改成如下:

Html2
    <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中加入:

Code2
        string[] str = new string[] { "aa""bb" };
        rpt1.DataSource 
= str;
        rpt1.DataBind();

运行结果如下:

Code3
    <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的话..就要注意了.

Code3
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;

上边的代码,你想想会出现什么结果? 先自己想想...

实际显示输出如下:

Result1
Table Id:table1 
Row Id:row1 
Cell Id:cell1

Table Id:ctl00_ContentPlaceHolder1_table1 
Row Id:ctl00_ContentPlaceHolder1_row1 
Cell Id:cell1  

但是页面HTML源代码是:

Result2
    <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之前还是之后..囧..码完字,闪了~~

原文地址:https://www.cnblogs.com/KenBlove/p/1362490.html