如何在自定义控件中呈现 aspx 页面中的内容
How can I render content from an aspx page in a custom control
我正在编写一个复合控件,它应该在使用的 aspx 页面中呈现放置在它的开始和结束标记之间的任何内容。
VB
Public Class MyComposite
Inherits CompositeControl
Implements INamingContainer
Public Property UserContentTemplate as ITemplate = Nothing
Public Overrides ReadOnly Property Controls() As ControlCollection
Get
EnsureChildControls()
Return MyBase.Controls
End Get
End Property
Protected Overrides Sub CreateChildControls()
' This is where I'm creating the controls
' for the composite
End Sub
Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
' This is where I render the composite controls
End Sub
Protected Overrides Sub RecreateChildControls()
EnsureChildControls()
End Sub
Public Overrides Sub DataBind()
CreateChildControls()
ChildControlsCreated = True
MyBase.DataBind()
End Sub
End Class
从这里开始,UserContentTemplate
在消费 aspx 页面中可用
<cc:MyComposite runat="server" ID="MyCompositeID">
<UserContentTemplate>
<asp:Button... />
<asp:TextBox... />
</UserContentTemplate>
</cc:MyComposite>
此时,asp:Button
和 asp:TextBox
没有被渲染。我已经查看了这个 link Building Templated Custom ASP.NET Serv Controls,但我不知道这是否适用或如何在我的情况下应用它。如果您查看 link,您会看到 <StatsTemplate>
标记内有 HTML 元素,这些元素在自定义控件中呈现。
HTML 的以下函数 returns 渲染控件的 HTML。
您可以使用占位符添加所有用于渲染的控件并将占位符传递给函数,或者您可以直接传递您的控件。
Public Function RenderUserControlToString(ByRef WebControl As Control) As String
Dim sb As StringBuilder = New StringBuilder
Dim sw As StringWriter = New StringWriter(sb)
Dim htw As HtmlTextWriter = New HtmlTextWriter(sw)
Try
WebControl.RenderControl(htw)
Catch ex As Exception
sb.Append(ex.Message & vbCrLf & ex.StackTrace)
End Try
Return sb.ToString()
End Function
我在这里找到了答案:Web Control Templates Explained written by Miguel Castro。这篇文章有助于阐明我在问题中引用的 Microsoft 文章中发生的事情。
Imports System.Web.UI
Imports System.Web.UI.WebControls
Public Class MyTemplate
Inherits CompositeControl
Implements INamingContainer
End Class
Public Class MyComposite
Inherits CompositeControl
Implements INamingContainer
<
TemplateContainer(GetType(MyTemplate)),
PersistenceMode(PersistenceMode.InnerProperty)
> _
Public Property UserContentTemplate as ITemplate = Nothing
Public Overrides ReadOnly Property Controls() As ControlCollection
Get
EnsureChildControls()
Return MyBase.Controls
End Get
End Property
Protected Overrides Sub CreateChildControls()
' I prepend the template to the Controls collection
If UserContentTemplate IsNot Nothing Then
Dim template = New MyTemplate()
UserContentTemplate.InstantiateIn(template)
Controls.Add(template)
End If
' Create and add other controls here
End Sub
Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
' This is where I render the composite controls
writer.AddAttribute(HtmlTextWriterAttribute.Class, "my-class")
writer.RenderBeginTag(TagKey)
For Each ctl As Control In Controls
ctl.RenderControl(writer)
Next
writer.RenderEndTag()
End Sub
Protected Overrides Sub RecreateChildControls()
EnsureChildControls()
End Sub
End Class
要点
- 创建一个 class (
MyTemplate
) 继承 来自 CompositeControl
和 实现 INamingContainer
- 用类型为
MyTemplate
的 TemplateContainer
属性修饰 UserContentTemplate
- 在
CreateChildControls
中实例化UserContentTemplate
- 渲染所有
Render
覆盖 中的控件
- 删除
DataBind
覆盖,我不需要它
一旦在 aspx 页面中使用 UserContentTemplate
标记,就会实例化 UserContentTemplate
。
<cc:MyComposite runat="server" ID="MyCompositeID">
<UserContentTemplate>
<asp:Button... />
<asp:TextBox... />
</UserContentTemplate>
</cc:MyComposite>
此答案中的代码解决了能够使用模板在复合控件中呈现消费者(开发人员)内容的问题。
我正在编写一个复合控件,它应该在使用的 aspx 页面中呈现放置在它的开始和结束标记之间的任何内容。
VB
Public Class MyComposite
Inherits CompositeControl
Implements INamingContainer
Public Property UserContentTemplate as ITemplate = Nothing
Public Overrides ReadOnly Property Controls() As ControlCollection
Get
EnsureChildControls()
Return MyBase.Controls
End Get
End Property
Protected Overrides Sub CreateChildControls()
' This is where I'm creating the controls
' for the composite
End Sub
Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
' This is where I render the composite controls
End Sub
Protected Overrides Sub RecreateChildControls()
EnsureChildControls()
End Sub
Public Overrides Sub DataBind()
CreateChildControls()
ChildControlsCreated = True
MyBase.DataBind()
End Sub
End Class
从这里开始,UserContentTemplate
在消费 aspx 页面中可用
<cc:MyComposite runat="server" ID="MyCompositeID">
<UserContentTemplate>
<asp:Button... />
<asp:TextBox... />
</UserContentTemplate>
</cc:MyComposite>
此时,asp:Button
和 asp:TextBox
没有被渲染。我已经查看了这个 link Building Templated Custom ASP.NET Serv Controls,但我不知道这是否适用或如何在我的情况下应用它。如果您查看 link,您会看到 <StatsTemplate>
标记内有 HTML 元素,这些元素在自定义控件中呈现。
HTML 的以下函数 returns 渲染控件的 HTML。
您可以使用占位符添加所有用于渲染的控件并将占位符传递给函数,或者您可以直接传递您的控件。
Public Function RenderUserControlToString(ByRef WebControl As Control) As String
Dim sb As StringBuilder = New StringBuilder
Dim sw As StringWriter = New StringWriter(sb)
Dim htw As HtmlTextWriter = New HtmlTextWriter(sw)
Try
WebControl.RenderControl(htw)
Catch ex As Exception
sb.Append(ex.Message & vbCrLf & ex.StackTrace)
End Try
Return sb.ToString()
End Function
我在这里找到了答案:Web Control Templates Explained written by Miguel Castro。这篇文章有助于阐明我在问题中引用的 Microsoft 文章中发生的事情。
Imports System.Web.UI
Imports System.Web.UI.WebControls
Public Class MyTemplate
Inherits CompositeControl
Implements INamingContainer
End Class
Public Class MyComposite
Inherits CompositeControl
Implements INamingContainer
<
TemplateContainer(GetType(MyTemplate)),
PersistenceMode(PersistenceMode.InnerProperty)
> _
Public Property UserContentTemplate as ITemplate = Nothing
Public Overrides ReadOnly Property Controls() As ControlCollection
Get
EnsureChildControls()
Return MyBase.Controls
End Get
End Property
Protected Overrides Sub CreateChildControls()
' I prepend the template to the Controls collection
If UserContentTemplate IsNot Nothing Then
Dim template = New MyTemplate()
UserContentTemplate.InstantiateIn(template)
Controls.Add(template)
End If
' Create and add other controls here
End Sub
Protected Overrides Sub Render(ByVal writer As HtmlTextWriter)
' This is where I render the composite controls
writer.AddAttribute(HtmlTextWriterAttribute.Class, "my-class")
writer.RenderBeginTag(TagKey)
For Each ctl As Control In Controls
ctl.RenderControl(writer)
Next
writer.RenderEndTag()
End Sub
Protected Overrides Sub RecreateChildControls()
EnsureChildControls()
End Sub
End Class
要点
- 创建一个 class (
MyTemplate
) 继承 来自CompositeControl
和 实现INamingContainer
- 用类型为
MyTemplate
的 - 在
CreateChildControls
中实例化 - 渲染所有
Render
覆盖 中的控件
- 删除
DataBind
覆盖,我不需要它
TemplateContainer
属性修饰 UserContentTemplate
UserContentTemplate
一旦在 aspx 页面中使用 UserContentTemplate
标记,就会实例化 UserContentTemplate
。
<cc:MyComposite runat="server" ID="MyCompositeID">
<UserContentTemplate>
<asp:Button... />
<asp:TextBox... />
</UserContentTemplate>
</cc:MyComposite>
此答案中的代码解决了能够使用模板在复合控件中呈现消费者(开发人员)内容的问题。