TL;DR...
When creating a [UserControl]
with single use templates, is it possible to get make server-side controls placed within those templates to render their id
without the UserControl
or container IDs?
In my ASP.NET web application I've create a UserControl
with multiple single-use template (I've only given the code here for one of those templates)...
Public Class MyUserCtrl
Inherits System.Web.UI.UserControl
Private Class MyUserCtrlLiteralContainer
Inherits Control
Implements INamingContainer
End Class
<TemplateContainer(GetType(MyUserCtrlLiteralContainer)),
TemplateInstance(TemplateInstance.Single),
PersistenceMode(PersistenceMode.InnerProperty)>
Public Property FirstTemplate As ITemplate
Private Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Init
If FirstTemplate IsNot Nothing Then
Dim container As New MyUserCtrlLiteralContainer()
FirstTemplate.InstantiateIn(container)
plhFirst.Controls.Add(container)
End If
End Sub
End Class
(Note, plhFirst
is a <asp:PlaceHolder>
in the mark-up)
This is an example of the control being used in a page (controlled by a Master
page)...
<asp:Content runat="server" ID="content" ContentPlaceHolderID="mainContent">
<uc1:MyUserCtrl runat="server" id="muc1">
<FirstTemplate>
<asp:Button runat="server" id="btnMyButton" />
</FirstTemplate>
</uc1:MyUserCtrl>
</asp:Content>
When the <asp:Button>
is rendered to the HTML, the id
of the element results in...
id="ctl00_content_muc1_ctl00_btnMyButton"
... where the second ctl00
is the ID of the MyUserCtrlLiteralContainer
instance.
Is there any way to make the id
of the control render as follows? (So the ID of the container is not used)
ctl00_content_muc1_btnMyButton
Or even better, is there any way to make the id
of the control render as follows? (So neither the ID of the usercontrol or container is used)
ctl00_content_btnMyButton
Alternatively, is there a different way to instantiate the controls in the UserControl
that would result in either of the above?
The button
id
includesmuc1
andctl00
because UserControl and MyUserCtrlLiteralContainer implement INamingContainer. If you don’t want theid
to include those parts, but you do want theid
to include other ancestor IDs, then you can’t use those control types.Removing
ctl00
: Unless you specifically need a custom container control, you can delete MyUserCtrlLiteralContainer and just instantiate the template directly in the PlaceHolder.Removing
muc1
: You must rewrite your UserControl as a server control that doesn't implement INamingContainer.Here’s a sample implementation:
Note: To avoid possible ID conflicts, I intentionally leave
plhFirst.ID
unset.I don't believe you are going to be able to get the IDs to look as you wish because they were designed to show control hierarchy, ugly as they are.
You can, however use static IDs on a control, page, or entire project if you wish. Check out this handy ScottGu article from way back in 2010:
https://weblogs.asp.net/scottgu/cleaner-html-markup-with-asp-net-4-web-forms-client-ids-vs-2010-and-net-4-0-series
The section you'll be looking for is
Today’s Cleaner Markup Topic: Client IDs