【问题标题】:Render multiple control collections in ASP.NET custom control在 ASP.NET 自定义控件中呈现多个控件集合
【发布时间】:2011-01-27 16:42:15
【问题描述】:

我已经构建了一个自定义 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>

该控件包含两个 ControlCollection 属性,“Contents”和“Footer”。从来没有尝试用多个控件集合构建一个控件,但是这样解决(简化):

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

无法找到 ID 为“KeywordTextBox”的控件 与标签“KeywordLabel”相关联。

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

感谢您的回复。

【问题讨论】:

    标签: c# asp.net custom-controls rendering controlcollection


    【解决方案1】:

    您可以使用两个面板作为两个控件集合的父级(它们将提供分组并提高可读性)。将每个集合中的控件添加到相应面板的 Controls 集合中,并在 Render 方法中调用每个面板的 Render 方法。面板会自动渲染它们的子元素,并为它们提供自己的命名空间,因此,您可以在不同的面板中拥有具有相似 ID 的控件。

    【讨论】:

      【解决方案2】:

      我不确定这是否可行。但是,如果您使用模板,则可以让控件正确呈现输出。

      首先,定义一个类作为容器控件的类型:

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

      【讨论】:

      • 我遇到了与 op 类似的问题,但这是行不通的。您不能引用 ITemplates 中的任何控件,因为它们没有正确实例化,这违背了此类控件的目的。
      猜你喜欢
      • 2011-11-24
      • 1970-01-01
      • 2010-09-06
      • 2010-10-07
      • 2012-11-09
      • 2011-01-17
      • 2013-07-26
      • 2011-08-25
      • 2012-08-21
      相关资源
      最近更新 更多