C# 在ASP.NET自定义控件中呈现多个控件集合

C# 在ASP.NET自定义控件中呈现多个控件集合,c#,asp.net,custom-controls,rendering,controlcollection,C#,Asp.net,Custom Controls,Rendering,Controlcollection,我构建了一个自定义WebControl,其结构如下: <gws:ModalBox ID="ModalBox1" HeaderText="Title" runat="server"> <Contents> <asp:Label ID="KeywordLabel" AssociatedControlID="KeywordTextBox" runat="server">Keyword: </asp:Label><br /&g

我构建了一个自定义WebControl,其结构如下:

<gws:ModalBox ID="ModalBox1" HeaderText="Title" runat="server">
    <Contents>
        <asp:Label ID="KeywordLabel" AssociatedControlID="KeywordTextBox" runat="server">Keyword: </asp:Label><br />
        <asp:TextBox ID="KeywordTextBox" Text="" runat="server" />
    </Contents>
    <Footer>(controls...)</Footer>
</gws:ModalBox>
然而,它似乎能够正确地呈现,如果我在属性中添加一些asp.net标签和输入控件,它将不再工作(请参见上面的asp.net代码)。我将获得HttpException:

找不到id为“KeywordTextBox”的控件 与标签“KeywordLabel”关联

有些可以理解,因为标签出现在controlcollection中的文本框之前。但是,对于默认的asp.net控件,它确实可以工作,那么为什么不能工作呢?我做错了什么?甚至可以在一个控件中包含两个控件集合吗?我应该以不同的方式呈现它吗


谢谢你的回复。

我不确定这是否行得通。但是,如果使用模板,则可以使控件正确渲染输出

首先,定义要用作容器控件类型的类:

public class ContentsTemplate : Control, INamingContainer
{
}
现在是自定义控件:

[PersistChildren(false), ParseChildren(true)]
public class ModalBox : CompositeControl
{

  [PersistenceMode(PersistenceMode.InnerProperty)]
  [TemplateContainer(typeof(ContentsTemplate))]
  public ITemplate Contents { get; set; }

  [PersistenceMode(PersistenceMode.InnerProperty)]
  [TemplateContainer(typeof(ContentsTemplate))]
  public ITemplate Footer { get; set; }

  protected override void CreateChildControls()
  {
    Controls.Clear();

    var contentsItem = new ContentsTemplate();
    Contents.InstantiateIn(contentsItem);
    Controls.Add(contentsItem);

    var footerItem = new ContentsTemplate();
    Footer.InstantiateIn(footerItem);
    Controls.Add(footerItem);
  }

}

您可以使用两个面板作为两个控件集合的父级(它们将提供分组和改进的可读性)。将每个集合中的控件添加到各个面板的控件集合中,在Render方法中只需调用每个面板的Render方法。面板将自动呈现其子对象,并为其提供自己的命名空间,因此,您可以在不同的面板中使用具有类似ID的控件。

我遇到了与op类似的问题,这将不起作用。您不能引用ITemplates中的任何控件,因为它们没有正确实例化,这违背了此类控件的用途。
[PersistChildren(false), ParseChildren(true)]
public class ModalBox : CompositeControl
{

  [PersistenceMode(PersistenceMode.InnerProperty)]
  [TemplateContainer(typeof(ContentsTemplate))]
  public ITemplate Contents { get; set; }

  [PersistenceMode(PersistenceMode.InnerProperty)]
  [TemplateContainer(typeof(ContentsTemplate))]
  public ITemplate Footer { get; set; }

  protected override void CreateChildControls()
  {
    Controls.Clear();

    var contentsItem = new ContentsTemplate();
    Contents.InstantiateIn(contentsItem);
    Controls.Add(contentsItem);

    var footerItem = new ContentsTemplate();
    Footer.InstantiateIn(footerItem);
    Controls.Add(footerItem);
  }

}