Я отредактировал весь ответ на основе нашего обсуждения. Вот рабочий и проверенный пример. У нас ниже двух элементов управления - ParentControl
и ChildControl
. ParentControl
отображается через Intellisense, где ChildControl
отображается только как дочерний элемент ParentControl
, как вы и хотели. Для простых целей рендеринга дети отрисовывают как теги li и выводят свое свойство 'text'. Родительский элемент управления обеспечивает отображение каждого дочернего элемента во время его собственного события RenderContents
.
Детский контроль:
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace TestControls
{
[ToolboxItem(false), Bindable(false)]
public class ChildControl : WebControl
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
base.Render(writer);
//render the text property as a list item for example's sake
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.Write(this.Text);
writer.RenderEndTag();
}
[Browsable(true)]
public string Text { get; set; }
}
}
Родительский контроль:
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace TestControls
{
[ToolboxData("<{0}:ParentControl runat=\"server\"></{0}:ParentControl>")]
[DefaultProperty("Children"), ParseChildren(true, "Children")]
public class ParentControl : WebControl
{
private List<ChildControl> _children;
protected override void RenderContents(HtmlTextWriter writer)
{
base.RenderContents(writer);
//create a div, and write some sample text
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.Write("Parent Control. Children:");
//create a ul, and ask each child control to render
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
foreach (ChildControl child in _children)
{
child.RenderControl(writer);
}
//close all tags
writer.RenderEndTag();
writer.RenderEndTag();
}
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public virtual List<ChildControl> Children
{
get
{
if (_children == null)
_children = new List<ChildControl>();
return _children;
}
}
}
}
В моей разметке я зарегистрировал элементы управления через пространство имен:
<%@ Register TagPrefix="test" Namespace="TestControls" %>
А потом добавил немного разметки:
<test:ParentControl ID="test" runat="server">
<test:ChildControl ID="child" Text="Hello World from Child 1" runat="server" />
<test:ChildControl ID="child2" Text="Hello World from Child 2" runat="server" />
</test:ParentControl>
В приведенной выше разметке Intellisense обнаруживает внешний родительский элемент управления, но не видит дочерний элемент управления. Как только курсор окажется внутри родительского элемента управления, Intellisense обнаружит тег ChildControl
по желанию.
Окончательный результат:
Родительский контроль. Дети:
* Hello World from Child 1
* Hello World from Child 2
Кроме того, вот хорошая статья о том, как работает создание всей интеллигенции , за которой я следовал, чтобы создать вышеописанное.
Надеюсь, это поможет. Вам все равно придется иметь дело с рендерингом на уровне дочернего элемента управления, который вы считаете подходящим для ваших конкретных элементов управления, однако вышеприведенное позволяет начать работу и удовлетворить потребность в работающей модели Intellisense.