FindControl в Custom ITemplate

У меня есть пользовательский UserControl, который использует простой 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 intellisense, но ошибка компиляции, что это ноль, когда я на самом деле загружаю страницу.

Чтобы найти выпадающий список в шаблоне, я использую:

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>

2 ответа

Решение

Я решил это, изменив UserControl, который использовал ITemplate. По какой-то причине он звонил InstantiateIn в OnPreRender, что явно слишком поздно для того, чтобы отрисовать что-либо, что будет подхвачено Page_Load на странице - см. Page LifeCycle и UserControls (наполовину вниз). я переехал InstantiateIn в OnInit в UserControl, и проблема решилась сама собой.

Страница веб-формы Asp.net:

<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>

определите класс Expander следующим образом:

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);
Другие вопросы по тегам