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

发布于 2024-08-25 08:25:55 字数 1831 浏览 2 评论 0原文

我构建了一个自定义 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 控件它确实可以工作,那么为什么它不起作用呢?我做错了什么?一个控件中是否可以有两个控件集合?我应该以不同的方式呈现它吗?

感谢您的回复。

I've build a custom WebControl, which has the following structure:

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

The control contains two ControlCollection properties, 'Contents' and 'Footer'. Never tried to build a control with multiple control collections, but solved it like this (simplified):

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

However it seems to render properly, it doesn't work anymore if I add some asp.net labels and input controls inside the property (see above asp.net code). I'll get the HttpException:

Unable to find control with id 'KeywordTextBox' that
is associated with the Label 'KeywordLabel'.

Somewhat understandable, because the label appears before the textbox in the controlcollection. However, with default asp.net controls it does work, so why doesn't this work? What am I doing wrong? Is it even possible to have two control collections in one control? Should I render it differently?

Thanks for replies.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

迷迭香的记忆 2024-09-01 08:25:55

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

You can use two Panels as parents of your two control collections (and they would provide grouping and improved readability). Add your controls from each collection to the Controls collection of respective panel, and in the Render method just call Render methods of each panel. Panels will automatically render their children, and will provide them with their own namespace, so, you can have controls with similar IDs in different panels.

初熏 2024-09-01 08:25:55

我不确定这是否有效。但是,如果您使用模板,您可以获得正确渲染输出的控件。

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

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

}

I'm not sure that will work. If you make use of templates however you can get the control to render output correctly.

First, define a class to be used as the type for the container control:

public class ContentsTemplate : Control, INamingContainer
{
}

And now the custom control:

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

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文