Визуализация нескольких коллекций элементов управления в настраиваемом элементе управления ASP.NET - PullRequest
9 голосов
/ 15 марта 2010

Я создал собственный 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: «Содержимое» и «Нижний колонтитул». Никогда не пытался создать элемент управления с несколькими коллекциями элементов управления, но решил его так (упрощенно):

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

Невозможно найти элемент управления с идентификатором KeywordTextBox, который связан с меткой KeywordLabel.

В некоторой степени понятно, потому что метка появляется перед текстовым полем в контрольной коллекции. Однако со стандартными элементами управления asp.net это работает, так почему же это не работает? Что я делаю неправильно? Возможно ли даже иметь два набора элементов управления в одном элементе управления? Должен ли я сделать это по-другому?

Спасибо за ответы.

Ответы [ 2 ]

2 голосов
/ 25 марта 2010

Вы можете использовать две панели в качестве родительских для ваших двух контрольных коллекций (и они обеспечат группирование и улучшенную читаемость). Добавьте ваши элементы управления из каждой коллекции в коллекцию Controls соответствующей панели, а в методе Render просто вызовите методы Render каждой панели. Панели будут автоматически визуализировать своих дочерних элементов и предоставят им свое собственное пространство имен, поэтому у вас могут быть элементы управления с одинаковыми идентификаторами на разных панелях.

1 голос
/ 19 марта 2010

Я не уверен, что это сработает. Однако, если вы используете шаблоны, вы можете получить элемент управления для правильной визуализации вывода.

Сначала определите класс, который будет использоваться в качестве типа для элемента управления контейнера:

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

}
...