C# – ASP.NET Custom control with content templates

asp.netccustom-controlsuser-controls

I creating the "clone" of LoginView ASP.NET control in ASP.NET 3.5, for our company needs and I'm trying to understand how it achieved the ability to set controls with same ID in different templates.
For example this is ASPX markup with LoginView control:

    <asp:LoginView ID="lv" runat="server">
        <AnonymousTemplate>
            <asp:Label ID="lbl" runat="server" />
        </AnonymousTemplate>
        <LoggedInTemplate>
            <asp:Label ID="lbl" runat="server" />
        </LoggedInTemplate>
    </asp:LoginView>

This is valid markup and page works fine.
Now I created my custom control:

    [ParseChildren(true)]
    [PersistChildren(false)]
    public class ContentControl : Panel
    {
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public PlaceHolder AnonymousView { get; set; }

        [PersistenceMode(PersistenceMode.InnerProperty)]
        public PlaceHolder LoggedinView { get; set; }

        public ContentControl()
        {
            this.Init += new EventHandler(ContentControl_Init);
        }

        void ContentControl_Init(object sender, EventArgs e)
        {
            if (AnonymousView == null)
            {
                AnonymousView = new PlaceHolder();
            }

            if (LoggedinView == null)
            {
                LoggedinView = new PlaceHolder();
            }

            this.Controls.Add(AnonymousView);
            this.Controls.Add(LoggedinView);

            AnonymousView.ID = "AnonymousView";
            LoggedinView.ID = "LoggedinView";

            AnonymousView.Visible = !MyContext.IsLogged;
            LoggedinView.Visible = MyContext.IsLogged;
        }
    }

Now when I use my control with following markup, I receive the error that control with ID "lbl" exists more than once on page:

    <TL:ContentControl ID="c" runat="server" CssClass="dd">
        <AnonymousView>
            AnonymousView
            <asp:Label ID="lbl" runat="server" />
        </AnonymousView>
        <LoggedinView>
            LoggedinView
            <asp:Label ID="lbl" runat="server" />
        </LoggedinView>
    </TL:ContentControl>

How I can allow to have controls with same ID in both templates?

Best Answer

You need to develop templated control: Building Templated Custom ASP.NET Server Controls

And use control that implement INamingContainer as template container: Use TemplateInstance.Single to avoid FindControls