我根据我们的讨论编辑了整个答案。这是一个有效且经过测试的示例。我们有以下两个控件 - ParentControl 和 ChildControl。 ParentControl 通过 Intellisense 可见,其中 ChildControl 仅作为 ParentControl 的子级可见。出于简单的渲染目的,孩子渲染为 li 标签并输出他们的“文本”属性。父控件确保每个子控件在其自己的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
另外,这里有一个good article on how the whole intellisence creation works,我按照它来创建上面的。
我希望这会有所帮助。您仍然需要以您认为适合您的特定控件的方式处理子控件级别的渲染,但是上面的内容可以帮助您入门并且确实满足工作 Intellisense 模型的需要。