Recently I had to face the following scenario: I was trying to create a customized gridview which automatically loaded an also customized template for the pager that fully integrated with some custom object that I was receiving from an external library.

In short, I needed to generate some controls in a dynamic way and decorate them with client capabilities. I thought that using the clientID will do the trick but I was surprised by the fact that when you add some control to your page/control you cannot get the proper clientID property until PreRender event of the page/control life cycle.

So if one of your added controls need to make reference to another one in a generated client script you better get sure that you’re retrieving the clientID on the PreRender event of this control.

I will post you an example to better explain all this:

'we create some controls 
Dim bt as New Button With {.ID="bt"}
Dim slider as New Panel With {.ID="slider"}

'and then we add it to the page or control
'in this case I'm creating a Template 
'so I'm creating them into the InstantiateIn method of the ITemplate
'container makes reference to the control where this template resides.
container.Controls.Add(bt)
container.Controls.Add(slider)

'now we want to create some client script code involving this two controls
'if we do this now it won't work.
'Our clientID will be just "bt", not "ContentPlaceHolder1_gw_bt" as it would be expected
'if this control was added to a gridview in a page using a MasterPage 
_grid.Page.ClientScript.RegisterStartupScript _
(Me.GetType,"script",String.Format("$('#{0}').click();", bt.ClientID),True)

'to get this working you can do this:
AddHandler slider.Prerender, _
Sub (o As Object, e As EventArgs)
     _grid.Page.ClientScript.RegisterStartupScript(Me.GetType,"script", _
     String.Format("$('#{0}').click();", bt.ClientID),True)
End Sub

'This way the client script will be resolved on PreRender I will be able to get the real clientID of the generated controls.