Accessing Controls in ListView Templates
Today when doing some application building I came across a case where I wanted to embed a ASP control inside one of the template of the asp:ListView control. This is legal and simple todo, however it has some interesting effects. Since the control is embedded in a template it is not made available in the code behind file and in my case I wanted to be able to access the control in the code behind file. Here is an example of what my markup looked like:
<asp:ListView ID="ListView1" runat="server">
<LayoutTemplate>
<table>
<tr>
<td><asp:PlaceHolder ID="ItemPlaceHolder" runat="server"></asp:PlaceHolder></td>
</tr>
<tr>
<td>
<asp:Button ID="ButtonTest" runat="server" Text="Button" />
</td>
</tr>
</table>
</LayoutTemplate>
</asp:ListView>
I searched the Internet for a solution to this problem and many of the common solutions to the problem I found where to hooked to ItemCreated or DataBound event from the ListView, then using FindControl to find the control and store it in a variable that was part of the page class. While this is entirely doable it leads to really clunky code and there is a much better method for doing this. Controls have the same life cycle methods that the page itself has an by handling the Init event for the button I can get access to the button as soon as it is created and store a copy off that can be used when other parts of the page fire events.
Here is the change to the markup above:
<asp:Button ID="ButtonTest" runat="server" Text="Button" oninit="ButtonTest_Init" />
And here is what the code behind looks like:
public partial class _Default : System.Web.UI.Page {
Button ButtonTest;
protected void ButtonTest_Init(object sender, EventArgs e) {
ButtonTest = (Button)sender;
ButtonTest.Text = "Foo";
}
protected void ListView1_ItemDeleted(object sender, ListViewDeletedEventArgs e) {
ButtonTest.Text = "Add";
}
}
The ButtonTest_Init event handler stores the button in ButtonTest and changes it's text. You will also note that because I've done this I can now access the button inside other event handlers the ListView may fire, which was my initial goal. All in a very clean manner not hooking ListView events and not calling FindControl.
Comments
Anonymous
March 25, 2008
PingBack from http://msdnrss.thecoderblogs.com/2008/03/26/accessing-controls-in-listview-templates/Anonymous
August 07, 2008
This is the closest I've come to finding a solution to my own problem. I have two labels in the listview templates. I've bound data to these labels using the <%#Eval()> thingy. The question I should be asking is how to get these bound values in the code behind.Anonymous
December 04, 2008
Excellent work. Your approach is infinitely easier (and cleaner) than littering one's code with FindControl calls.Anonymous
October 19, 2009
good idea, its better than findcontrolAnonymous
November 03, 2009
Percect, thanks for this solution!Anonymous
November 03, 2009
Could you supply a VB version of this code ?Anonymous
December 09, 2009
Excellent, thank you for posting! Took a lot of searching to get here - I was trying to populate DropDownLists within an InsertItemTemplate on page load and this cleanly solves the problem.Anonymous
March 19, 2010
Thanks, better than FindControl in many situations!Anonymous
December 26, 2010
thanks you!with FindControl i not access control inside <editItemtemplate></> of listviewAnonymous
July 18, 2011
Wow. This is so simple it's genious. I never comment on these posts but what you have done here has relieved my soul avoiding that darn FindControl() method. I love it! Keep up the great work!Anonymous
December 21, 2011
I know this post has been up a long time but... THANK YOU!Anonymous
March 03, 2012
It's 2012 and the post is still awsome!Anonymous
January 16, 2014
www.kettic.com/.../listview.shtml