5.5 ClientIDMode属性
有过ASP.NET 4之前版本开发经验的读者可能知道,当赋给一个服务器端控件的ID值时,这个ID值并非是控件真正在浏览器中展现时的HTML的ID值。ASP.NET会默认把父控件的ID值用“_”区分附加到自己的ID前面,因此在HTML中看到控件的ID值经常是类似于这种形式的字符串:“ctl0_UserControl1_ctl01_Textbox1”。
这种ID的生成方式对于后台代码来说并没有什么影响,但是却给客户端的操作带来了很多的不便。例如,不能直接在客户端JavaScript代码中使用“Textbox1”这种ID形式的值。因此,只能够使用ClientID属性来获取,如下面示例将获取Textbox1控件的ID:
<script type="text/javascript">
function GetControlID()
{
alert('<%=Textbox1.ClientID%>');
}
</script>
当然,这种方式虽然不失为一种优雅的解决方案,但是我们更希望能够完全控制客户端ID。在ASP.NET 4中对于所有的控件都增加了一个ClientIDMode属性,可以使用此属性来影响ASP.NET用于生成控件的ClientID值的算法,从而更加方便地控制控件客户端ID。该属性是一个枚举类型,它有四个枚举值。其原型如下面的代码所示:
using System;
namespace System.Web.UI
{
public enum ClientIDMode
{
Inherit=0,
AutoID=1,
Predictable=2,
Static=3,
}
}
1.Inherit
在默认情况下,页面上的所有控件都使用值为Inherit的ClientIDMode,它表示控件将使用与其父控件相同的ClientIDMode,即这个值指定控件像它的父控件一样产生ID。
为了测试ClientIDMode属性的值,首先创建一个用户控件LoadControl.ascx,并在该控件里添加一个TextBox控件,并将ClientIDMode属性设置为Inherit。如下所示:
<asp:TextBox ID="TextBox1"runat="server"
ClientIDMode="Inherit"></asp:TextBox>
设置好用户控件之后,来将该控件加入到宿主页面TestLoadControl.aspx里,同时继续在页面添加一个TextBox控件。如下所示:
<uc1:LoadControl ID="LoadControl1"runat="server"/>
<asp:TextBox ID="TextBox1"runat="server"
ClientIDMode="Inherit"></asp:TextBox>
运行TestLoadControl.aspx页面并查看页面代码,你会发现上面定义的两个TextBox控件会生成如下两个input元素。如下面的代码所示:
<input name="LoadControl1$TextBox1"type="text"
id="LoadControl1_TextBox1"/>
<input name="TextBox1"type="text"id="TextBox1"/>
其中,用户控件LoadControl.ascx里的TextBox控件的ID生成为“LoadControl1TextBox1”,即该ID由父控件ID“LoadControl1”加分离符“”加子控件ID“TextBox1”组成;而宿主页面TestLoadControl.aspx里的TextBox控件的ID生成为“TextBox1”,因为它没有父控件。
2.AutoID
它采用了与ASP.NET 3.5一样的算法来生成ClientID属性。因为页面上的所有控件在默认情况下都使用值为Inherit的ClientIDMode,所以将现有ASP.NET应用程序转移到ASP.NET 4,不会改变运行时用来生成客户端ID的算法,除非对ClientIDMode属性进行更改。如果将上面的两个TextBox控件的ClientIDMode属性设置为AutoID,它产生的结果如下所示:
<input name="LoadControl1$TextBox1"type="text"
id="LoadControl1_TextBox1"/>
<input name="TextBox1"type="text"id="TextBox1"/>
3.Static
如果将ClientIDMode属性设置为Static,最终产生的控件ID将保持原有的值,ASP.NET框架不再修改以确保ID唯一,而完全由开发者负责。如果将上面的两个TextBox控件的ClientIDMode属性设置为Static,它产生的结果如下所示:
<input name="LoadControl1$TextBox1"type="text"id="TextBox1"/>
<input name="TextBox1"type="text"id="TextBox1"/>
如上面的代码所示,如果页面上存在重复的ID值,一定会破坏任何通过ID值来搜索DOM元素的脚本。因此,当决定使用Static属性时,请注意保持ID的唯一性。
4.Predictable
如果ClientIDMode属性设置为Predictable值,最终产生的控件ID是可以预测的。尤其在数据绑定控件中,它将会使用父控件ID加自身ID,再加上设置的ClientIDRowSuffix属性值而生成客户端ID。
例如,下面的ListView将绑定到一系列Employee对象。每个对象都具有EmployeeID和IsSalaried属性。ClientIDMode和ClientIDRowSuffix属性的组合告诉CheckBox控件生成类似于EmployeeList_IsSalaried_8的客户端ID,其中8表示关联员工的ID。
<asp:ListView runat="server"ID="EmployeeList"
ClientIDMode="Predictable"
ClientIDRowSuffix="EmployeeID">
<ItemTemplate>
<asp:CheckBox runat="server"
ID="IsSalaried"
Checked='<%#Eval("IsSalaried")%>'/>
</ItemTemplate>
</asp:ListView>