2

I have a custom UserControl which uses a simple 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>

The template is rendered with two simple properties:

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

Everything displays correctly, but I can't use FindControl within the template. I get a reference to my combobox from VS intellisense, but a compilation error that it's null whern I actually load the page.

To find the combobox in th the template, I'm using:

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

And the actual template looks like this on the page:

<l49:Expander runat="server" ID="optionsExpander">
    <ContentTemplate>
        ... other controls
            <asp:DropDownList ID="cboFilterCriticality" runat="server" ValidationGroup="filterGrid" DataTextField="Key" DataValueField="Value" />
    </ContentTemplate>
</l49:Expander>
Jeremy
  • 8,902
  • 2
  • 36
  • 44
Echilon
  • 10,064
  • 33
  • 131
  • 217
  • Good question. Seems like it should work, but I get the same issue. I can see the control if I look at the controls collection in the watch window. You could always override the FindControl method. – Chris Mullins Jun 01 '12 at 14:48
  • That's what `FindControlRecursive` does, recursively iterates over the tree looking for my control, to no avail. – Echilon Jun 02 '12 at 17:19

2 Answers2

1

I resolved this by changing the UserControl which used an ITemplate. For some reason, it was calling InstantiateIn in OnPreRender, which is clearly way too late to render anything to be picked up by Page_Load in the page - see the Page LifeCycle and UserControls (half way down). I moved InstantiateIn to OnInit in the UserControl, and the problem solved itself.

Echilon
  • 10,064
  • 33
  • 131
  • 217
0

The Asp.net's WebForm page:

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

define the Expander class as following:

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

    }
}

in OnInit of Page:

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

and finally in Javascript :

var containerID = ViewState("ContentTemplateContainerID");
var elID = $get(containerID)[0].id;
var expander = $find(elID);
Siamand
  • 1,080
  • 10
  • 19