从父页面访问 UserControl 中基于模板的控件
Accessing template-based controls in UserControl from parent page
在开始之前,我不是询问如何从父页面访问 UserControl 中托管的服务器端控件。这个问题已经被问过很多次了,这不是那个的重复。
这个问题是关于放置在 UserControl 实例的 模板 项中的服务器端控件。
在 ASP.NET 中,我有一个带有多个模板处理程序的 UserControl,这导致 HTML 块使用 单个实例 呈现每个模板的(它不像 <asp:Repeater>
模板被多次使用)。例如:
<uc1:MyUserControl runat="server" ID="myCtrl1">
<TopControls>
<asp:Literal runat="server" ID="litTop" />
</TopControls>
<BottomControls>
<asp:Button runat="server" id="btnBottom" />
</BottomControls>
</uc1:MyUserControl>
而 UserControl 的设置类似于...
<div class="myUserControl">
<div class="topControls">
<asp:PlaceHolder runat="server" id="plhTopControls" />
</div>
<div class="bottomControls">
<asp:PlaceHolder runat="server" id="plhBottomControls" />
</div>
</div>
问题是,为了让 父页面 访问控件,我必须在 UserControl 中有一个方法来找到它们:
Public Overrides Function FindControl(id As String) As System.Web.UI.Control
Dim ctrl As Control = Nothing
If Not TopControlsContainer Is Nothing Then
ctrl = TopControlsContainer.FindControl(id)
End If
If ctrl Is Nothing AndAlso Not BottomControlsContainer Is Nothing Then
ctrl = BottomControlsContainer.FindControl(id)
End If
If ctrl Is Nothing Then
ctrl = MyBase.FindControl(id)
End If
Return ctrl
End Function
这是因为Visual Studio2015设计器不再将这两个服务器端控件视为属于页面,而是属于UserControl,所以我必须在页面并在 Page_Load
:
中设置它们
Protected WithEvents litTop as Literal
Protected WithEvents btnBottom as Button
litTop = myCtrl1.FindControl("litTop")
btnBottom = myCtrls.FindControl("btnBottom")
是否可以设置 UserControl 以便模板中的服务器端控件由父页面的设计器文件选取,所以我不这样做每次我在该 UserControl 中添加新的 UserControl 或服务器端控件时都必须执行此操作吗?
如果用 UserControl 做不到,是否可以用服务器端控件做? (如果是这样,那需要什么属性?)
在 MyUserControl.ascx.vb 中,用 TemplateInstanceAttribute, specifying TemplateInstance.Single 修饰 ITemplate 属性。 (默认为多个。)来自文档:
A single instance of a template allows you to reference controls that are contained within the template.
VB.NET:
<PersistenceMode(PersistenceMode.InnerProperty)>
<TemplateInstance(TemplateInstance.Single)>
Public Property TopControls As ITemplate
<PersistenceMode(PersistenceMode.InnerProperty)>
<TemplateInstance(TemplateInstance.Single)>
Public Property BottomControls as ITemplate
C#:
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateInstance(TemplateInstance.Single)]
public ITemplate TopControls { get; set; }
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateInstance(TemplateInstance.Single)]
public ITemplate BottomControls { get; set; }
编译代码并重新保存父页面后,Visual Studio 设计器将为模板内声明的控件生成支持字段。
注意:如果模板仅实例化一次,您应该只指定TemplateInstance.Single。
在开始之前,我不是询问如何从父页面访问 UserControl 中托管的服务器端控件。这个问题已经被问过很多次了,这不是那个的重复。
这个问题是关于放置在 UserControl 实例的 模板 项中的服务器端控件。
在 ASP.NET 中,我有一个带有多个模板处理程序的 UserControl,这导致 HTML 块使用 单个实例 呈现每个模板的(它不像 <asp:Repeater>
模板被多次使用)。例如:
<uc1:MyUserControl runat="server" ID="myCtrl1">
<TopControls>
<asp:Literal runat="server" ID="litTop" />
</TopControls>
<BottomControls>
<asp:Button runat="server" id="btnBottom" />
</BottomControls>
</uc1:MyUserControl>
而 UserControl 的设置类似于...
<div class="myUserControl">
<div class="topControls">
<asp:PlaceHolder runat="server" id="plhTopControls" />
</div>
<div class="bottomControls">
<asp:PlaceHolder runat="server" id="plhBottomControls" />
</div>
</div>
问题是,为了让 父页面 访问控件,我必须在 UserControl 中有一个方法来找到它们:
Public Overrides Function FindControl(id As String) As System.Web.UI.Control
Dim ctrl As Control = Nothing
If Not TopControlsContainer Is Nothing Then
ctrl = TopControlsContainer.FindControl(id)
End If
If ctrl Is Nothing AndAlso Not BottomControlsContainer Is Nothing Then
ctrl = BottomControlsContainer.FindControl(id)
End If
If ctrl Is Nothing Then
ctrl = MyBase.FindControl(id)
End If
Return ctrl
End Function
这是因为Visual Studio2015设计器不再将这两个服务器端控件视为属于页面,而是属于UserControl,所以我必须在页面并在 Page_Load
:
Protected WithEvents litTop as Literal
Protected WithEvents btnBottom as Button
litTop = myCtrl1.FindControl("litTop")
btnBottom = myCtrls.FindControl("btnBottom")
是否可以设置 UserControl 以便模板中的服务器端控件由父页面的设计器文件选取,所以我不这样做每次我在该 UserControl 中添加新的 UserControl 或服务器端控件时都必须执行此操作吗?
如果用 UserControl 做不到,是否可以用服务器端控件做? (如果是这样,那需要什么属性?)
在 MyUserControl.ascx.vb 中,用 TemplateInstanceAttribute, specifying TemplateInstance.Single 修饰 ITemplate 属性。 (默认为多个。)来自文档:
A single instance of a template allows you to reference controls that are contained within the template.
VB.NET:
<PersistenceMode(PersistenceMode.InnerProperty)>
<TemplateInstance(TemplateInstance.Single)>
Public Property TopControls As ITemplate
<PersistenceMode(PersistenceMode.InnerProperty)>
<TemplateInstance(TemplateInstance.Single)>
Public Property BottomControls as ITemplate
C#:
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateInstance(TemplateInstance.Single)]
public ITemplate TopControls { get; set; }
[PersistenceMode(PersistenceMode.InnerProperty)]
[TemplateInstance(TemplateInstance.Single)]
public ITemplate BottomControls { get; set; }
编译代码并重新保存父页面后,Visual Studio 设计器将为模板内声明的控件生成支持字段。
注意:如果模板仅实例化一次,您应该只指定TemplateInstance.Single。