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