23

How do I access a Control in the LayoutTemplate of a ListView control?

I need to get to litControlTitle and set its Text attribute.

<asp:ListView ID="lv" runat="server">
  <LayoutTemplate>
    <asp:Literal ID="litControlTitle" runat="server" />
    <asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
  </LayoutTemplate>
  <ItemTemplate>
  </ItemTemplate>
</asp:ListView>

Any thoughts? Perhaps via the OnLayoutCreated event?

Bob Kaufman
  • 12,864
  • 16
  • 78
  • 107
craigmoliver
  • 6,499
  • 12
  • 49
  • 90

5 Answers5

35

Try this:

((Literal)lv.FindControl("litControlTitle")).Text = "Your text";
tanathos
  • 5,566
  • 4
  • 34
  • 46
  • I tried that initially, but that didn't work. Then I came here. Thanks though! – craigmoliver Jan 11 '09 at 22:57
  • 3
    very strange... I place this code inside the callback of OnLayoutCreated, and when I bind the ListView it works fine... – tanathos Jan 11 '09 at 23:08
  • oh, well I didn't put it in that event, trying now – craigmoliver Jan 11 '09 at 23:11
  • 9
    For anyone reading this answer, make sure you call `FindControl` after the `ListView` has been bound to a source (i.e., after calling `DataBind` on you ListView). Otherwise the ListView's Layout Template will not be ready by the time you look up the control, hence `FindControl` will not succeed. – asm00 Jan 17 '14 at 16:30
  • Also: if data binding occurs on an empty collection then the control cannot be found. Do a null reference check for this situation. – John K Feb 20 '16 at 00:08
17

The complete solution:

<asp:ListView ID="lv" OnLayoutCreated="OnLayoutCreated" runat="server">
  <LayoutTemplate>
    <asp:Literal ID="lt_Title" runat="server" />
    <asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
  </LayoutTemplate>
  <ItemTemplate>
  </ItemTemplate>
</asp:ListView>

In codebehind:

protected void OnLayoutCreated(object sender, EventArgs e)
{
    (lv.FindControl("lt_Title") as Literal).Text = "Your text";
}
Vindberg
  • 1,502
  • 2
  • 15
  • 27
  • This solution is more stable than tanathos's. tanathos's sometimes doesn't work when DataBind and access in the same method. – Gqqnbig Nov 06 '15 at 01:19
4

This technique works for template layout; use the init event of the control:

<asp:ListView ID="lv" runat="server" OnDataBound="lv_DataBound">
  <LayoutTemplate>
    <asp:Literal ID="litControlTitle" runat="server" OnInit="litControlTitle_Init" />
    <asp:PlaceHolder ID="itemPlaceHolder" runat="server" />
  </LayoutTemplate>
  <ItemTemplate>
  </ItemTemplate>
</asp:ListView>

And capture a reference to the control for use in the code-behind (e.g) in the ListView's DataBound event:

private Literal litControlTitle;

protected void litControlTitle_Init(object sender, EventArgs e)
{
    litControlTitle = (Literal) sender;
}

protected void lv_DataBound(object sender, EventArgs e)
{
    litControlTitle.Text = "Title...";
}
JonH
  • 261
  • 3
  • 12
0

For Nested LV Loop:

void lvSecondLevel_LayoutCreated(object sender, EventArgs e)
{
    Literal litText = lvFirstLevel.FindControl("lvSecondLevel").FindControl("litText") as Literal;
    litMainMenuText.Text = "This is test";
}
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
Dheeraj Palagiri
  • 1,829
  • 3
  • 23
  • 46
0

In case you need the VB version, here it is

Dim litControl = CType(lv.FindControl("litControlTitle"), Literal)
litControl.Text = "your text"
Jeff
  • 1,362
  • 14
  • 17