自定义 ITemplate 中的 FindControl

本文关键字:FindControl 中的 ITemplate 自定义 | 更新日期: 2023-09-27 18:35:36

我有一个自定义的用户控件,它使用一个简单的ITemplate:

<asp:Panel runat="server" ID="pnlExpander" CssClass="expander">
    <asp:HyperLink runat="server" ID="lnkExpand" Text="More Options" NavigateUrl="#" CssClass="lnkExpand"/>
    <asp:Panel runat="server" ID="pnlContent" CssClass="expanderContent" style="display: none">
        <asp:PlaceHolder runat="server" ID="plcContent"/>
    </asp:Panel>
</asp:Panel>

模板使用两个简单的属性呈现:

public class Expander {
    private ITemplate _contentTemplate;
        public ITemplate ContentTemplate {
            get { return _contentTemplate; }
            set { _contentTemplate = value; }
    }
    protected override void OnPreRender(EventArgs e) {
            if (ContentTemplate != null) {
                ContentTemplate.InstantiateIn(plcContent);
            }
    }

所有内容都正确显示,但我无法在模板中使用 FindControl。我从 VS 智能感知中获得了对我的组合框的引用,但编译错误表明它为空,因为我实际上加载了页面。

要在模板中找到组合框,我正在使用:

var cboFilterCriticality = AspNetUtils.FindControlRecursive(optionsExpander,"cboFilterCriticality") as DropDownList;

实际模板在页面上如下所示:

<l49:Expander runat="server" ID="optionsExpander">
    <ContentTemplate>
        ... other controls
            <asp:DropDownList ID="cboFilterCriticality" runat="server" ValidationGroup="filterGrid" DataTextField="Key" DataValueField="Value" />
    </ContentTemplate>
</l49:Expander>

自定义 ITemplate 中的 FindControl

我通过更改使用ITemplate的用户控件来解决此问题。出于某种原因,它在OnPreRender中调用InstantiateIn,这显然为时已晚,无法呈现任何内容以供页面中的Page_Load拾取 - 请参阅页面生命周期和用户控件(一半)。我InstantiateIn移动到用户控件中的OnInit,问题自行解决。

Asp.net 的 WebForm 页面:

<asp:Panel runat="server" ID="pnlExpander" CssClass="expander">
    <asp:HyperLink runat="server" ID="lnkExpand" Text="More Options" NavigateUrl="#" CssClass="lnkExpand"/>
    <asp:Panel runat="server" ID="pnlContent" CssClass="expanderContent" style="display: none">
        <asp:PlaceHolder runat="server" ID="plcContent"/>
    </asp:Panel>
</asp:Panel>

按如下方式定义扩展器类:

public class Expander { 
    public ITemplate ContentTemplate {get ;set;}
    public HtmlGenericControl ContentTemplateContainer{get;set;}
    protected override void OnInit(EventArgs e) {
        this.ContentTemplateContainer = new HtmlGenericControl("div");
        if (ContentTemplate != null) {
            ContentTemplate.InstantiateIn(container);
        }
        plcContent.Controls.Add(container);
    }
}

在页面的 OnInit 中:

public override void OnInit(EventArgs e){
    base.OnInit(e);
    ViewState["ContentTemplateContainerID"] =  ContentTemplateContainer.ClientID;
}

最后在 Javascript 中:

var containerID = ViewState("ContentTemplateContainerID");
var elID = $get(containerID)[0].id;
var expander = $find(elID);