Find Controls With _ctl
When you just can't get the reference you need, this trick can be a lifesaver.
October 30, 2009
asp.netNOW Tip
LANGUAGE: VB .NET
Find Controls With _ctl
When you just can't get the reference you need, thistrick can be a lifesaver.
By Don Kiely
In my first production ASP.NET application, the project'sWeb designer created a beautiful, highly usable design. Users loved it, but itwas a bear to code. The hard part was that the app frequently had to grab areference to an individual control embedded within a DataGrid or DataList.For example, the design required programmatic interaction with server controlslocated deep within a HeaderTemplate(yes, we had controls in the header), ItemTemplate,and EditItemTemplate within a DataList control. I had to do thingssuch as populate drop-down lists in a single row of the DataGrid or DataListwhen the user clicked on a button that fired the EditCommand event. This was gnarly stuff, particularly because Istarted coding the app during the beta phase of .NET with, um, incompletedocumentation.
(Note: If the previous paragraph made no sense, read thedocumentation for how DataGrids, DataLists, and Repeater server controls work. You also should look at the HTMLthese controls produce.)
As you now know (because you have examined the HTML fromvarious states of DataGrid and DataList controls), ASP.NET identifieseach HTML control with a unique ID - a three-part name. In the .aspx page, ifthe DataList is called dlProjections, the control I'minterested in is called txtPositionID,and the user has opted to edit the second record listed, the source in thebrowser will have the name attribute on the element with a value ofdlProjections:_ctl2:txtPositionID.
The center part of the colon-delimited name, _ctl2, is thekey to getting programmatic access to the control. The "_ctl" is the defaultunique name for the control, with the row number appended. (It's a zero-basedvalue, with zero representing the header row.) Because the user clicked on theedit button of the second row in the DataListin this case, the middle portion of the unique name is _ctl2.
So how do you use this? In your code, you obviously knowthe name of the DataGrid or DataList control, the name of thecontrol you want, and in most events you have access to the index of the rowwith the second parameter passed into the event (usually with a variable nameof e). Here's an example of the many ways you can put this to use.
The procedure, in this case the EditCommand event procedure, starts by getting the index of the rowusing e.Item.ItemIndex. Then itbuilds a string of the form "_ctl2" and uses multiple levels of the FindControl method to drill down intothe hierarchy of controls in the DataList(in this case) for the control you want:
Private Sub dlIndustries_EditCommand(ByVal source As Object, _
ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) _
Handles dlCompanies.EditCommand
dlCompanies.EditItemIndex = e.Item.ItemIndex
BindDataList() 'bind the dataand display it
Dim ctl AsString = "_ctl" & (e.Item.ItemIndex + 1).ToString
Dim ddl AsDropDownList
ddl =CType(dlCompanies.FindControl(ctl).FindControl("lstRegionUpdate"),DropDownList)
...
Now ddl has a reference to the control you want, and youcan manipulate it as any other control.
This isn't a technique you want to use as a first step.Many times FindControl will zeroright into the control you want. But if you can't get the reference you needthat way, this trick can be a lifesaver.
Don Kiely is senior information architect for Third SectorTechnologies, a business and technology consultancy in Fairbanks, Alaska. Whenhe isn't living and breathing ASP.NET and XML, he is exploring the Alaskawilderness with his dog Mardy, hiking, whitewater kayaking, skiing, andsearching for true love. Reach him at mailto:[email protected].
About the Author
You May Also Like