Web 窗体控件 ID 解析

更新:2007 年 11 月

当您声明 Web 服务器控件的 ID 属性以通过编程方式访问该控件时,ASP.NET 页框架将自动确保声明的 ID 在整个 ASP.NET Web 应用程序中是唯一的。

命名容器

ASP.NET 页框架通过 INamingContainer 接口为应用程序提供自动控件 ID 解决方案,该接口为实现它的每个类生成一个“命名容器”。命名容器在 ASP.NET 网页控件层次结构中定义一个新的 ID 命名空间。这样,命名容器便允许页框架为在该命名空间内生成的每个 Control 对象的 UniqueID 属性生成一个值。UniqueID 属性不同于您声明的 ID 属性,因为它是控件的完全限定标识符。

实现 INamingContainer 的类包括:PageDataListGridViewDataListItemDataGridItemRepeater。通常,可以创建子控件的那些控件都会动态实现 INamingContainer

Page 类充当该页的控件层次结构中的顶级命名容器。

数据绑定方案中的名称解析

页框架提供的自动名称解决方案在数据绑定方案中很重要。请考虑下面的示例,该示例演示页中声明的控件。

<asp:Repeater id="MyDataList" runat="server">
  <ItemTemplate>
    <asp:Label id="MyLabel" Text="<%# Container.ToString() %>" runat="server"/><br />
  </ItemTemplate>
</asp:Repeater>
<hr />
<asp:Label id="ResultsLabel" runat="server" AssociatedControlID="MyDataList"/>
<asp:Repeater id="MyDataList" runat="server">
  <ItemTemplate>
    <asp:Label id="MyLabel" Text="<%# Container.ToString() %>" runat="server"/><br />
  </ItemTemplate>
</asp:Repeater>
<hr />
<asp:Label id="ResultsLabel" runat="server" AssociatedControlID="MyDataList"/>

Label 控件绑定到数据源,而 Repeater 控件循环访问该数据源中的项时,该页必须能够以编程的方式区分 Label 控件的不同实例,即使您只为每个实例指定了 ID MyLabel 也是如此。页框架通过对每个控件使用完全限定的 UniqueID 属性来实现这一点。例如,下面的代码生成了 Label 控件的三个版本,并将它们的 UniqueID 属性值写入该页。

  <script language="vb" runat="server">

      Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
          Dim sb As New StringBuilder()
          sb.Append("Container: " + _
          MyDataList.NamingContainer.ToString() + "<p>")

          Dim a As New ArrayList()
          a.Add("A")
          a.Add("B")
          a.Add("C")

          MyDataList.DataSource = a
          MyDataList.DataBind()

          Dim i As Integer
          Dim l As Label
          For i = 0 To MyDataList.Controls.Count - 1
              l = CType(CType(MyDataList.Controls(i), RepeaterItem).FindControl("MyLabel"), Label)
              sb.Append("Container: " & _
                 CType(MyDataList.Controls(i), RepeaterItem).NamingContainer.ToString() & _
                 "<p>")
              sb.Append("<b>" & l.UniqueID.ToString() & "</b><p>")
          Next
          ResultsLabel.Text = sb.ToString()
      End Sub
</script>
<script language="c#" runat="server">

  void Page_Load(Object sender, EventArgs e) 
  {
      StringBuilder sb = new StringBuilder();
      sb.Append("Container: " + 
          MyDataList.NamingContainer.ToString() + "<p>");

      ArrayList a = new ArrayList();
      a.Add("A");
      a.Add("B");
      a.Add("C");

      MyDataList.DataSource = a;
      MyDataList.DataBind();

      for (int i = 0; i < MyDataList.Controls.Count; i++)
      {
          Label l = 
              (Label)((RepeaterItem)MyDataList.Controls[i]).FindControl("MyLabel");
          sb.Append("Container: " + 
              ((RepeaterItem)MyDataList.Controls[i]).NamingContainer.ToString() + 
              "<p>");
          sb.Append("<b>" + l.UniqueID + "</b><p>");
      }
      ResultsLabel.Text = sb.ToString();
}
</script>

当请求此页时,它将下面的内容写入该页:

  • 名为 MyDataList 的 Repeater 控件的命名容器。此命名容器取决于指定给 .aspx 文件的名称。

    hw8sf6fb.alert_note(zh-cn,VS.90).gif说明:

    如果此示例的 .aspx 文件是 MySample1.aspx,则命名容器的类是 ASP.mysample1_aspx,但命名容器是 Page。

  • 充当命名容器的下一个控件的实例,即 Repeater 控件。此容器的名称是随同它的整个命名空间限定符一起显示的。

  • Repeater 控件内每个 Label 控件的 UniqueID 属性。

    hw8sf6fb.alert_note(zh-cn,VS.90).gif说明:

    请不要编写使用生成的 UniqueID 属性的值引用控件的代码。可以将 UniqueID 属性视为一个句柄(例如,通过将它传递到进程),但不应指望它拥有特定结构。

请参见

任务

如何:在 ASP.NET 网页中按 ID 查找子控件

如何:访问 Web 服务器控件的命名容器的成员

概念

ASP.NET Web 服务器控件概述

使用 NamingContainer 属性确定控件的命名容器