Steve Wash
Steve Wash

Reputation: 986

Can't reference PlaceHolder in Code Behind

I'm building an ASP.NET user control that contains a repeater. In the ItemTemplate, I've dropped a PlaceHolder. I'm trying to display a Group Header in the Place Holder whenever a boolean field in the datasource is true.

The Repeater works fine, loads and displays all data except the Group Header. However, Visual Studio won't let me reference the PlaceHolder in the code behind. Error message is "The name 'PlaceHolder1' does not exist in the current context". I looked at other similar problems and tried using FindControl, but it returns null.

    <%@ Control Language="C#" ClassName="Table1Control" AutoEventWireup="true"         CodeBehind="Table2View.ascx.cs" Inherits="CCC.Table2View" %>

        <table>
        <asp:Repeater ID="Table2List" runat="server" onitemdatabound="Table2List_ItemDataBound">
    <HeaderTemplate>

            <tr class="Table2HeaderRow">
                <th class = "Table2Col1Hdr">Test/Report Group</th>
                <th class = "Table2Col2Hdr">Agent</th>
                <th class = "Table2Col3Hdr">Disk Content</th>
                <th class = "Table2CriteriaSetHdr">
                    <table class="Table2CriteriaSetTable">
                        <tr class="Table2CriteriaSetInnerRow">
                            <td class = "Table2CriteriaSetTopHdr" colspan=3>Zone Diameter </td></tr>
                        <tr class="Table2CriteriaSetInnerRow">
                            <td class="Table2CriteriaSetSHdr">S</td>
                            <td class="Table2CriteriaSetIHdr">I</td>
                            <td class="Table2CriteriaSetRHdr">R</td>
                        </tr>
                    </table>
                </th>
                <th class = "Table2CriteriaSetHdr">
                    <table class="Table2CriteriaSetTable">
                        <tr class="Table2CriteriaSetInnerRow">
                            <td class = "Table2CriteriaSetTopHdr" colspan=3>MIC Interperetive </td></tr>
                        <tr class="Table2CriteriaSetInnerRow">
                            <td class="Table2CriteriaSetSHdr">S</td>
                            <td class="Table2CriteriaSetIHdr">I</td>
                            <td class="Table2CriteriaSetRHdr">R</td>
                        </tr>
                    </table>
                </th>
                <th class = "Table2Col5Hdr">Comments</th>
            </tr>

    </HeaderTemplate>

    <ItemTemplate>
        <asp:PlaceHolder ID="PlaceHolder1" runat="server"></asp:PlaceHolder>
        <tr class = "<%# "Table2ItemRow" + Eval("IsNewDrugId").ToString() %>" >
            <td class="Table2ItemCol1"><asp:Label runat="server" ID="lblId"><%#Eval("TRGroup")%></asp:Label></td>
            <td class="Table2ItemCol2"><asp:Label runat="server" ID="Label1" class="AgentName"><%#Eval("_Agent.Name")%></asp:Label></td>
            <td class="Table2ItemCol3"><asp:Label runat="server" ID="Label2"><%#Eval("DiskContent")%></asp:Label></td>
            <td class="Table2CriteriaSetItem">
                <table class="Table2CriteriaSetTable">
                    <tr class="Table2CriteriaSetInnerRow">
                        <td class="Table2ItemS"><asp:Label runat="server" ID="Label3"><%#Eval("ZoneDiameterS")%></asp:Label></td>
                        <td class="Table2ItemI"><asp:Label runat="server" ID="Label4"><%#Eval("ZoneDiameterI")%></asp:Label></td>
                        <td class="Table2ItemR"><asp:Label runat="server" ID="Label5"><%#Eval("ZoneDiameterR")%></asp:Label></td>
                    </tr>
                </table></td>
            <td class="Table2CriteriaSetItem">
                <table class="Table2CriteriaSetTable">
                    <tr class ="Table2CriteriaSetInnerRow">
                        <td class="Table2ItemS"><asp:Label runat="server" ID="Label6"><%#Eval("MICriteriaS")%></asp:Label></td>
                        <td class="Table2ItemI"><asp:Label runat="server" ID="Label7"><%#Eval("MICriteriaI")%></asp:Label></td>
                        <td class="Table2ItemR"><asp:Label runat="server" ID="Label8"><%#Eval("MICriteriaR")%></asp:Label></td>
                    </tr>
                </table></td>
            <td class="Table2ItemCol10"><asp:Label runat="server" ID="Label9"><%#Eval("Comment")%></asp:Label></td>
        </tr>
    </ItemTemplate>
</asp:Repeater>
</table>

And the code behind:

protected void Table2List_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
    //PlaceHolder1.Controls.Clear();  // Can't find this ???
    ///PlaceHolder groupHeader = (PlaceHolder)FindControl("PlaceHolder1");  // returns null???
    PlaceHolder groupHeader = (PlaceHolder)e.Item.FindControl("PlaceHolder1");  // as suggested by Servy, still returns null
    groupHeader.Controls.Clear();
    if(e.Item.ItemType == ListItemType.Item  || e.Item.ItemType == ListItemType.AlternatingItem)
    {
        Table2Row T2Data = (Table2Row)e.Item.DataItem;
        if (T2Data.IsNewGroup)
        {
            TableRow tr = new TableRow();
            tr.CssClass = "Table2GroupHeader";
            TableCell td = new TableCell();
            td.ColumnSpan = 6;
            Label lbl = new Label();
            lbl.Text = T2Data.GroupHeader;

            td.Controls.Add(lbl);
            tr.Controls.Add(td);
            groupHeader.Controls.Add(tr);
        }
    }
}

Upvotes: 1

Views: 3892

Answers (1)

Servy
Servy

Reputation: 203842

You need to use: e.Item.FindControl("controlName") since the control is in the repeater.

Remember that the control is't just on the Page directly, so you won't be able to access it via FindControl on the page. You will only be able to access it from an row-based event on Repeater that provides a RepeaterItemEventArgs to access the control from code behind.

Upvotes: 4

Related Questions