views:

1094

answers:

4

Hi,

I have the following problem (I'll explain it simplified because otherwise it would get too complicated/long).

I need to create an ASP.net server control that is inherited from Panel. Simple enough. When the custom control renders, it should dynamically create a Button, associate an event handler to it (which will also be defined inside the server control) and add this button to the rendered control. The click event handler defined inside the server control does some job which for the moment isn't interesting.

I already coded an example and that works fine. In the constructor of the server control I create a new button control, give it an ID, associate an event handler, on the OnInit of the server control I add the button to the Panel controls (remember, my control inherits from Panel) and then everything gets rendered. This looks something like the following:

public class MyCustomControl: Panel
    {
        private Button myButton;

        public MyCustomControl()
        {
            myButton = new Button();
            myButton.ID = "btnTest";
            myButton.Click += new EventHandler(btnTest_Click);
        }

        protected void btnTest_Click(object sender, EventArgs e)
        {
            //do something...
        }

        //...

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            this.Controls.AddAt(0, myButton);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            //...
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
        }


        protected override void Render(HtmlTextWriter output)
        {
            base.RenderContents(output);
        }
    }

This works quite fine. The button gets rendered correctly and when I click on it, the appropriate handler inside this customer server control is invoked and executed. Now the problem however starts when I would like to add multiple instances of this server control to my page because all of my generated buttons will have the same id "btnTest" which results in a conflict. So what I tried is to associate a random number to the id of the button, s.t. it end up being "btnTest1235512" or something similar. This solves my problem with the multiple IDs, but results in the problem that my event handler when clicking on the button is no more called correctly. I guess this is due to the problem that my button always gets another id when entering in the constructor and so the appropriate callback (btnTest_Click event handler) isn't found.

Can someone give me a suggestion how I could handle the problem. Is there some way for remembering the ID of the button and re-associating it. As far as I know however this has to happen in the OnInit, where the ViewState isn't yet available. So storing the id in the ViewState wouldn't work.

Any suggestions??

+3  A: 

Implementing INamingContainer should fix the problem. You can then keep naming all your buttons btnTest.

This is just a marker interface so you don't have to implement any methods or properties.

Ronald Wildenberg
Thanks, that was it. In the mean time I alternatively just appended the clientID of the Panel from which I inherit, but I will switch back to your solution, it's the right one. Thanks
Juri
A: 

Inherit from INamingContainer like:

public class MyCustomControl : Panel, INamingContainer
{
}

This is a marker interface and requires no implementation. I just verified with your code and it solves your problem.

JoshBerke
A: 

Check this question, it may help: .Net Changes the element IDs

Amr ElGarhy
A: 

Implementing INamingContainer will do it for you. It will automatically name the buttons with unique ID's. Just a note, if you need to use any of those buttons in any JavaScript, you'll need to use the ClientID property:

function getButton() {
  var myButton = document.getElementById('<%=btnTest.ClientID %>');
}
Brandon Montgomery