Я имею, создают пользовательский 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'.
Несколько понятный, потому что маркировка появляется перед текстовым полем в controlcollection. Однако со средствами управления asp.net по умолчанию это работает, итак, почему это не работает? Что я делаю неправильно? Даже возможно иметь два набора управления в одном управлении? Я должен представить его по-другому?
Спасибо за ответы.
Вы можете использовать две панели в качестве родителей двух коллекций элементов управления (и они обеспечат группировку и улучшат читабельность). Добавьте ваши элементы управления из каждой коллекции в коллекцию Controls соответствующей панели, а в методе Render просто вызовите методы Render каждой панели. Панели будут автоматически рендерить свои дочерние элементы и предоставлять им собственное пространство имен, так что вы можете иметь элементы управления с одинаковыми ID в разных панелях.
Я не уверен, что это сработает. Однако если использовать шаблоны, то можно добиться корректного вывода элементов управления.
Сначала определите класс, который будет использоваться в качестве типа для элемента управления контейнера:
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);
}
}