从父页面访问UserControl中的基于模板的控件

问题描述:

在我开始之前,我是而不是询问如何从父页面访问UserControl内托管的服务器端控件。这被问了很多次,这不是重复的。从父页面访问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> 

而且用户控件设置了类似...

<div class="myUserControl"> 
    <div class="topControls"> 
    <asp:PlaceHolder runat="server" id="plhTopControls" /> 
    </div> 
    <div class="bottomControls"> 
    <asp:PlaceHolder runat="server" id="plhBottomControls" /> 
    </div> 
</div> 

的问题是,为了的父页面访问控制,有必要对我来说,在用户控件有一个方法找到他们:

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 Studio 2015年的设计师不再认为两个服务器正面c ontrols属于该页面,而是将控制属于用户控件,所以我必须明确声明他们的页面,并设置它们在Page_Load

Protected WithEvents litTop as Literal 
Protected WithEvents btnBottom as Button 

litTop = myCtrl1.FindControl("litTop") 
btnBottom = myCtrls.FindControl("btnBottom") 

是否有可能成立UserControl以便模板中的服务器端控件由父页面的设计器文件拾取,所以我不必每次在该UserControl中添加一个新的UserControl或服务器端控件时都要经历这个操作?

如果用户控件不可行,是否可以通过服务器端控件进行操作? (如果是这样,那么需要哪些属性?)

在MyUserControl.ascx.vb中,用TemplateInstanceAttribute装饰ITemplate属性,指定TemplateInstance.Single。 (默认值为多个)。从文档:

模板的单个实例允许您引用模板中包含的控件。

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如果模板实例化一次。

+0

对不起,延迟回复 - 这是非常棒的,并完全解决我的问题 - 谢谢你:-)你也碰巧知道如何停止'内容不允许之间的元素开幕和结束标签'MyUserControl ''显示警告? – freefaller

+1

尝试将''属性添加到两个模板属性(除了TemplateInstance之外)。 –

+0

你,先生,是一个明星 - 完美 - 谢谢:-)我无法再分配19小时的赏金,但可以放心,这是你的 – freefaller