我正在开发一组自定义控件,其中一个是“父”,其他任何必须添加到此父级的ITemplate属性中。
但是在页面中,在设计时,我可以通过intellisense看到页面级别的其他控件,我可以在理论上将它们添加到任何地方。
我想模仿asp的行为:表和asp:TableRow,你不能直接在asp外面添加一个asp:TableRow:表...
有没有办法达到这个目标? 非常感谢!
编辑:我已经部分解决了KP建议,但是如果您阅读评论,那么这不是“真正的”方式(我认为)。 没人知道怎么做? :(
答案 0 :(得分:2)
我根据我们的讨论编辑了整个答案。这是一个经过实践检验的例子。我们有两个控件 - ParentControl
和ChildControl
。通过智能感知可以看到ParentControl
,其中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
另外,这是一个good article on how the whole intellisence creation works,我按照这个创建了上面的内容。
我希望这会有所帮助。您仍然需要以您认为适合特定控件的方式处理子控件级别的渲染,但是上面的内容可以帮助您开始并确实满足工作的Intellisense模型的需要。
答案 1 :(得分:0)
我以前做过这个,但我没有可用的代码。我可以告诉你,我通过在内置的ASP.NET Datagrid控件上使用Reflector来解决这个问题。我能够对“包含”(“行”)和“容器”(“网格”)之间的关系进行逆向工程。您必须使用属性以非常特定的方式将类排列在一起。