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>