我想创建一个理想的自定义控件:
<foo:Frobnicate runat="server">
<DoStuffWithThese>
<asp:TextBox runat="server" ID="fizzbot" />
</DoStuffWithThese>
<!-- other controls can be in the wrapper but outside the DoSomeStuffWithThese collection -->
<asp:DropDownList runat="server" ID="othercontrol" />
</foo:Frobnicate>
虽然我会在必要时解决这个问题:
<foo:Frobnicate runat="server">
<DoStuffWithThese>
<asp:TextBox runat="server" ID="fizzbot" />
</DoStuffWithThese>
<AndOtherStuffWithThese>
<asp:DropDownList runat="server" ID="othercontrol" />
</AndOtherStuffWithThese>
</foo:Frobnicate>
我可以在代码隐藏中访问控件(在第二个非理想示例中),但由于某种原因,他们的ID(我需要的)是NULL 。
以下是代码隐藏:
[ParseChildren(true)]
public class Frobnicate : WebControl {
[PersistenceMode(PersistenceMode.InnerProperty)]
public List<WebControl> DoStuffWithThese { get; set; }
[PersistenceMode(PersistenceMode.InnerProperty)]
public List<WebControl> AndOtherStuffWithThese { get; set; }
public override OnLoad(EventArgs e) {
base.OnLoad(e);
foreach(Control currentControl in DoStuffWithThese) {
// the control can be accessed (e.g. I can see it's a TextBox, etc.
// but currentControl.ID == null here -- why? :(
}
}
有谁知道这是为什么?更重要的是,我如何解决它,以便我可以获得其中一种格式的自定义控件并能够访问ID?
答案 0 :(得分:1)
我相信你必须在你的班级中实现INamingContainer
,WebControl本身不会这样做。请注意,它只是一个标记界面,您不需要任何代码。此外,您应该使用ITemplate
(它允许您实际创建控件并在控件的输出中使用它们)而不是控件列表。
这应该有用:http://msdn.microsoft.com/en-us/library/36574bf6(v=vs.85).aspx
如果这不是你想要的,请详细说明你实际上要做什么,以及为什么你不想使用模板。
要解释一下 - 只需添加对服务器控件的引用,您实际上并没有将它添加到页面/控件树的任何位置,这意味着它不是实际创建的,并且它不能作为页面的一部分,真的(包括一个有用的UniqueID / ClientID,几乎任何逻辑,除了构造函数)。
当您拥有模板时,您可以使用数据绑定来填写所需的数据等,例如,您可以使用FindControl
访问控件(或者只使用Controls
集合,但请注意,模板可能还包含文字和其他内容,而不仅仅是您的控件。)
答案 1 :(得分:0)
你能得到下拉列表的ID吗?如果是这样,我认为它与缺少runat = server的其他项目有关。