1

为我的自定义 ASP.net 服务器控件生成的 HTML 代码为子控件生成 name 属性,而不是 id 属性。像这样的东西:

<span id="GridView2_ctl02_editdis">
    <input type="text" name="GridView2$ctl02$editdis$ctl00"/>
</span>

自定义控件本身的 ID 显然是正确的。

对我来说更奇怪的是,有时确实会生成 ID (我不知道在什么条件下)。但是FindControl()具有该 ID 的 a 在服务器端返回 null。FindControl()使用 name 属性的值就可以了。

像这样的东西:

<span class="TextBox" id="GridView2_ctl02_editdis">
    <input type="text" id="GridView2_ctl02_editdis_ctl00" name="GridView2$ctl02$editdis$ctl00"/>
</span>

对于上述情况,FindControl("GridView2$ctl02$editdis$ctl00")工作正常,FindControl("GridView2_ctl02_editdis_ctl00")没有。

如何确保一致且可预测的 ID?

4

1 回答 1

3

它们是一致的。

在内部,作为命名控件(即 GridView)的子控件,它们的完整 ID 是通过使用“$”附加其父控件的 ID 来构建的。如果是网格,则为 gridID$rowID$cellID$mycontrolID。这对于区分同一子控件(即 mycontrolID)的多个实例是必要的。为什么是“$”而不是“_”?我猜是因为很多人已经倾向于将他们的控件命名为“my_control_something”,而“$”符号和任何符号一样好。

因此,GridView2$ctl02$editdis$ctl00 是正确的 ID,这就是为什么它被用作 INPUT 等控件的名称。当回发发生时,框架需要能够将表​​单键与适当的控件相匹配。

我认为,与 ID 混淆的原因在于,您在 .aspx 中使用的 ID 和您在 HTML 中看到的 ID 是两个不同的东西。客户端 ID 就是这样。无论出于何种原因,当一个控件被呈现时(使用 ClientID 属性),所有的“$”都会被替换为“_”。我的猜测是这样做是为了使其对 javascript/css 友好。

现在,关于 FindControl("GridView2$ctl02$editdis$ctl00")... 你真的应该尽可能避免使用它。FindControl 是一个递归函数,它将“GridView2$ctl02$editdis$ctl00”分解为“GridView2”和“ctl02$editdis$ctl00”,找到 GridView2 并询问它是否有“ctl02$editdis$ctl00”作为子控件。对以 $ 分隔的每个部分重复该过程。

附带说明一下,每当您发现自己调用 Page.FindControl 以获得一些深埋的控制时,您需要检查模式并询问原因。例如,无论需要使用“GridView2$ctl02$editdis$ctl00”做什么,很可能也需要使用“GridView2$ctl02$editdis$ctl01”来完成。在这种情况下,它可能需要在 OnItemCreated 或 OnItemDataBound 上进行处理,您可以在其中访问“知道”有关“ctl00”的行。

于 2009-04-11T16:57:19.147 回答