Reputation: 986
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
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