ASP.NET 4.0 Client ID 功能






4.41/5 (15投票s)
本文介绍了 ASP.NET 4.0 的 ClientID 功能及其在客户端开发中的相关属性。
引言
本文将重点介绍 ASP.NET Framework 4.0 中一项新功能。为了使客户端开发模式更轻松、提高生产力,已经付出了更多的努力。谈到客户端,我们都知道 ClientID,它可以为我们提供一个唯一的 ClientID 来在客户端引用控件。但到目前为止,它一直是只读的(您无法在代码中设置它)。您在客户端获得的 clientID 看起来像 ctl00_MasterPageBody_ctl01_Textbox1,假设其中 ctl00 是母版页上的内容占位符的内容 ID 等等。基本上,它继承了父控件或占位符的外部控件 ID,并生成一个唯一的 ID。
问题和解决方案的背景
问题
ClientID 属性在确保每个元素都唯一标识方面表现出色。但当您进行客户端脚本编写时,会变得更加困难,并且在 ASP.NET 中遇到问题,因为直到运行时您才知道客户端 ID 是什么,这使得进行任何类型的客户端脚本编写变得困难。此外,任何页面修改、添加或删除控件,都可能导致生成不同的客户端 ID。
解决方案
在我们迄今为止的 ASP.NET 版本中,这个问题有一个变通方法。每个控件都有一个名为 ClientID 的属性,它是只读的,并提供唯一的客户端 ID。您可以在代码隐藏中动态添加脚本时使用它,或者更常见的是使用内联代码将值提供给客户端脚本。
<script type="text/javascript">
function DoSomething() 
{
   alert('<%= Control.ClientID %>');
}
</script>
如果您移动控件或将控件设置为用户控件,您在客户端获得的 ClientID 属性会不断变化,例如 ctl00_MasterPageBody_ctl01_Textbox1,有时我们需要使用此唯一生成的 ID 来引用控件(我们大多数时候会硬编码值 :)放轻松,伙计)。
现在看看 ASP.NET 4.0 解决方案
ASP.NET 4.0 具有新的客户端 ID 功能,您可以在代码中设置它,并在设计时设置其他属性,并在运行时在客户端开发中使用它们。
ASP.NET 4.0 在 ASP.NET 控件上定义了一个新的属性,名为 ClientIDMode。一旦为控件设置了 ClientIDMode 属性,ClientID 就会相应地修改,然后用作客户端 ID。您甚至可以在控件本身上设置 ClientID 属性。
这个属性的酷之处在于,您可以将其设置在控件级别、页面级别或应用程序级别(在 web.config 文件中)。
所以现在让我们看看 Client ID 模式是什么以及它们做什么。
现在每个控件(包括页面和母版页,因为它们继承自控件)都有一个名为 ClientIDMode 的新属性,用于选择客户端 ID 的行为。ClientIDMode 支持下面给出的模式类型。
静态
这是最基础、最简单的模式,它使客户端 ID static。您为 ClientID 或 ID 放入的任何值都将用作客户端 ID。一个奇怪的条件是,如果 static ClientIDMode 用于重复控件,则开发人员负责确保客户端 ID 的唯一性。下面是代码示例
Markup: <asp:TextBox ID="txtEcho2" runat="server" ClientIDMode="Static" /> 
Output: <input id="Text1" name="ctl00$MasterPageBody$ctl00$txtEcho2" />
设置 ClientID 属性会将服务器端 ID 和客户端 ID 分开。您将拥有用于客户端开发的客户端 ID,这将使代码更轻松、更干净。
Markup: <asp:TextBox ID="TextBox1" ClientID="”Echo”" runat="server" 
	ClientIDMode="Static" /> 
Output: <input id="Text2" name="Echo" />
遗留代码
如果在控件层次结构中未设置 ClientIDMode,则其默认值为。这会导致客户端 ID 的行为方式与框架的 2.0 版本(3.0 和 3.5 没有更改此代码路径)相同。此模式将生成类似于 ctl00_MasterPageBody_ctl01_Textbox1 的 ID。下面是代码示例
Markup: <asp :TextBox ID ="txtEcho" runat ="server" ClientIDMode ="Legacy" />
Output: <input id="ctl00_MasterPageBody_ctl00_txtEcho" 
	name="ctl00$MasterPageBody$ctl00$txtEcho" />
Inherit (继承)
这是每个控件的默认行为。它会查找控件的父级以获取 ClientIDMode 的值。您无需在每个控件上设置此项,因为它是默认的,只有当 ClientIDMode 被更改并且期望的新行为是从控件的父级继承时,才会使用此项。
Predictable (可预测)
当您只有一个控件时,上述模式工作良好,但当涉及到数据绑定控件时,您会在控件内拥有不同的控件,会发生什么?例如,假设是一个中继器控件。
此模式的作用是,它会呈现客户端 ID,后面跟着某种可预测的后缀,但仍然足够独特,可以使每个单独的项目彼此不同。
此模式通常在数据绑定控件上使用,并且在框架需要确保唯一性时使用。框架将遍历控件层次结构,将提供的 ID 与其父控件 ID 加上前缀,直到到达控件层次结构中 ClientIDMode 定义为 static 的控件。如果控件放置在数据绑定控件内,则还会向提供的 ID 添加一个具有标识该实例的值的后缀。下面是代码示例
标记
<asp:GridView ID="EmployeesNoSuffix" runat="server" 
	AutoGenerateColumns="false" ClientIDMode="Predictable">
<Columns>
    <asp:TemplateField HeaderText="ID">
         <ItemTemplate>
              <asp:Label ID="EmployeeID" runat="server" Text='<%# Eval("ID") %>' />
         </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Name">
         <ItemTemplate>
              <asp:Label ID="EmployeeName" 
		runat="server" Text='<%# Eval("Name") %>' />
         </ItemTemplate>
    </asp:TemplateField>
</Columns>
</asp:GridView>
输出
<table id="EmployeesNoSuffix" style="border-collapse: collapse" 
	cellspacing="0" rules="all" border="1">
  <tbody>
    <tr>
       <th scope="col">ID</th>
       <th scope="col">Name</th>
    </tr>
    <tr>
       <td><span id="EmployeesNoSuffix_EmployeeID_0">1</span></td>
       <td><span id="EmployeesNoSuffix_EmployeeName_0">EmployeeName1</span></td>
    </tr>
    ...
    <tr>
      <td>
         <span id="EmployeesNoSuffix_EmployeeID_8">9</span>
      </td>
      <td>
         <span id="EmployeesNoSuffix_EmployeeName_8">EmployeeName9</span>
      </td>
    </tr>
  </tbody>
</table>
另一个有用的属性 RowClientIDSuffix 用于以用户友好的方式生成绑定控件的客户端 ID,并定义了 RowClientIDSuffix。它会在控件的数据键集合中查找值,然后将该值用作 ID 的后缀。
标记
<asp:GridView ID="EmployeesSuffix" runat="server" 
	AutoGenerateColumns="false" 
		ClientIDMode="Predictable" RowClientIDSuffix="ID">
  <Columns>
      <asp:TemplateField HeaderText="ID">
         <ItemTemplate>
            <asp:Label ID="EmployeeID" runat="server" Text='<%# Eval("ID") %>' />
         </ItemTemplate>
      </asp:TemplateField>
      <asp:TemplateField HeaderText="Name">
         <ItemTemplate>
            <asp:Label ID="EmployeeName" runat="server" Text='<%# Eval("Name") %>' />
         </ItemTemplate>
      </asp:TemplateField>
   </Columns>
</asp:GridView>
输出
<table id="EmployeesSuffix" style="border-collapse: collapse" 
	cellspacing="0" rules="all" border="1">
   <tbody>
      <tr>
          <th scope="col">ID</th>
          <th scope="col">Name</th>
      </tr>
      <tr>
          <td>
             <span id="EmployeesSuffix_EmployeeID_1">1</span>
          </td>
          <td>
             <span id="EmployeesSuffix_EmployeeName_1">EmployeeName1</span>
          </td>
      </tr>
      ...
      <tr>
          <td>
             <span id="EmployeesSuffix_EmployeeID_9">9</span>
          </td>
          <td>
             <span id="EmployeesSuffix_EmployeeName_9">EmployeeName9</span>
          </td>
      </tr>
   </tbody>
</table>
定义了 RowClientIDSuffix,但不是只有一个值,而是使用复合值。它表现与单个值相同,但会将两个值都附加到 ID。
标记
<asp:GridView ID="EmployeesCompSuffix" runat="server" AutoGenerateColumns="false" 
	ClientIDMode="Predictable" RowClientIDSuffix="ID, Name">
    <Columns>
          <asp:TemplateField HeaderText="ID">
               <ItemTemplate>
                    <asp:Label ID="EmployeeID" runat="server" 
			Text='<%# Eval("ID") %>' />
              </ItemTemplate>
         </asp:TemplateField>
        <asp:TemplateField HeaderText="Name">
             <ItemTemplate>
                   <asp:Label ID="EmployeeName" 
			runat="server" Text='<%# Eval("Name") %>' />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>
输出
<table id="EmployeesCompSuffix" style="border-collapse: collapse" 
			cellspacing="0" rules="all" border="1">
     <tbody>
         <tr>
               <th scope="col">ID</th>
               <th scope="col">Name</th>
         </tr>
         <tr>
             <td>
                 <span id="EmployeesCompSuffix_EmployeeID_1_EmployeeName1">1</span>
             </td>
             <td>
                 <span id="EmployeesCompSuffix_EmployeeName_1_EmployeeName1">
			EmployeeName1</span>
             </td>
          </tr>
          ..
          <tr>
              <td>
                 <span id="EmployeesCompSuffix_EmployeeID_9_EmployeeName9">9</span>
              </td>
              <td>
                 <span id="EmployeesCompSuffix_EmployeeName_9_EmployeeName9">
			EmployeeName9</span>
              </td>
          </tr>
     </tbody>
</table>
请分享您的想法和宝贵的建议。谢谢!
参考
历史
- 2009 年 3 月 15 日:初始帖子

