2010-03-15 125 views
9

多个控制集合我已经建立一个自定义的WebControl,它具有以下结构:渲染在ASP.NET自定义控件

<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> 

控制包含两个的ControlCollection属性,“内容”和“尾”。从来没有试图建立与多个控制集合控制,但解决它像这样(简化):

[PersistChildren(false), ParseChildren(true)] 
public class ModalBox : WebControl 
{ 
    private ControlCollection _contents; 
    private ControlCollection _footer; 

    public ModalBox() 
     : base() 
    { 
     this._contents = base.CreateControlCollection(); 
     this._footer = base.CreateControlCollection(); 
    } 

    [PersistenceMode(PersistenceMode.InnerProperty)] 
    public ControlCollection Contents { get { return this._contents; } } 

    [PersistenceMode(PersistenceMode.InnerProperty)] 
    public ControlCollection Footer { get { return this._footer; } } 

    protected override void RenderContents(HtmlTextWriter output) 
    { 
     // Render content controls. 
     foreach (Control control in this.Contents) 
     { 
      control.RenderControl(output); 
     } 

     // Render footer controls. 
     foreach (Control control in this.Footer) 
     { 
      control.RenderControl(output); 
     } 
    } 
} 

但是它似乎正确地呈现,它不会了,如果我加入一些asp.net标签和输入工作属性内的控件(参见上面的asp.net代码)。我将得到HttpException:

无法找到具有标识'KeywordLabel'与 关联的id为'KeywordTextBox'的控件。

有些可以理解,因为标签出现在controlcollection的文本框之前。但是,使用默认的asp.net控件它确实有效,那么为什么这不起作用呢?我究竟做错了什么?在一个控件中是否可以有两个控件集合?我应该以不同的方式呈现吗

感谢您的回复。

回答

2

您可以使用两种面板为你的两个家长控制集合(并且它们会提供分组和改进的可读性)。将每个集合中的控件添加到相应面板的Controls集合中,并在Render方法中调用每个面板的Render方法。面板将自动呈现他们的子女,并将为他们提供自己的名字空间,因此,您可以在不同面板中使用类似ID的控件。

+0

是的,这将工作! – 2010-09-11 09:16:16

1

我不确定这会起作用。如果您使用模板,但您可以使控件正确呈现输出。

首先,定义一个类被用作容器控件类型:

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); 
    } 

} 
+0

我遇到了与op类似的问题,这不起作用。您不能在ITemplates内部引用任何控件,因为它们没有正确实例化,这违背了此类控件的目的。 – mattmanser 2010-09-08 08:48:59