我正在尝试将复合控件呈现给字符串并将其写入页面:
Dim sb As New StringBuilder
Dim sw As New StringWriter(sb)
Dim hw As New HtmlTextWriter(sw)
Dim CustomCompositeControl as New MyCustomCompositeControl
CustomCompositeControl.RenderControl(hw)
HttpContext.Current.Response.Write(sb.ToString)
不幸的是,它只是渲染一个空的span标记。
甚至可以像在DataGrid中那样将CompositeControls渲染为字符串吗?
没有进入我的CompositeControl的文字内部,在通过RenderControl渲染之前,我应该在CompositeControl中确定一些内容吗?
注意:我没有覆盖CompositeControl中的RenderControl。我需要这样做吗?
更新 好。我有点想通了。我必须确保在RenderControl方法运行之前调用CompositeControl的EnsureChildControls方法。我不太确定在内部调用它的最佳位置。
答案 0 :(得分:2)
如果您有权访问简单地调用Render()方法,只需这样做,它将为您提供您正在寻找的结果。否则,是的,您将不得不重写RenderControl()...取决于您何时调用它,您可以通过调用Render()方法内部RenderControl()来逃脱。
另外,您应该注意复合控件的顶级html标记始终是一个span,除非您将其指定为其他内容,例如div:
/// <summary>
/// Render as div instead of the default span.
/// </summary>
/// <value></value>
/// <returns>HtmlTextWriterTag.Div</returns>
protected override HtmlTextWriterTag TagKey
{
get
{
return HtmlTextWriterTag.Div;
}
}
答案 1 :(得分:1)
是的,这是可能的,但是如果不了解控件内部及其对asp.net生命周期内各种事件的依赖性,是否可能?我不认为这是可能的。
例如,一个DataGrid可能依赖于在一个表单中,我的猜测是它会出错,表明没有表单。
答案 2 :(得分:0)
看看这个MSDN page discussing CompositeControls,特别是标题为“复合控件的渲染引擎”的部分
请求处理 代码(在Page类中)调用 EnsureChildControls之前 将PreRender事件触发到页面 和每个孩子控制。
在正常的ASP.NET请求期间,您在CompositeControl中覆盖的CreateChildControls()方法直到它到达请求生命周期的后期才会被调用,就在PreRender之前。如果您尝试在正常的ASP.NET页面生命周期之外渲染CompositeControl,则永远不会添加子控件,因为不会调用任何子控件创建方法。保证在手动渲染控件时调用EnsureChildControls()的最佳方法是覆盖RenderControl(),如下所示:
public override void RenderControl(HtmlTextWriter writer)
{
// We must explicitly call EnsureChildControls() in cases where we are rendering
// a CompositeControl outside of the normal ASP.NET page lifecycle
EnsureChildControls();
base.RenderControl(writer);
}
对我来说,CompositeControl类本身并没有以类似的方式覆盖RenderControl()方法,这似乎很奇怪。如果你使用Reflector来检查CompositeControl的实现细节,你会发现在类中重写的所有方法都只是为了调用EnsureChildControls();如果控件处于设计模式,甚至Render()也会调用EnsureChildControls()方法。来自Reflector:
protected internal override void Render(HtmlTextWriter writer)
{
if (base.DesignMode)
{
this.EnsureChildControls();
}
base.Render(writer);
}