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