3

I’m trying to dynamically declare an ImageButton.

I declare it and assign an ID and Image to it as follows:

ImageButton btn = new ImageButton();
btn.ImageUrl = "img/Delete.png";
btn.ID = oa1[i] + "_" + i;
btn.OnClick = "someMethod";

But when I try to assign an OnClick handler for the button it throws the following exception:

System.Web.UI.WebControls.ImageButton.OnClick is inaccessible due to protection level
Christophe Geers
  • 8,564
  • 3
  • 37
  • 53
Kemoid
  • 45
  • 2
  • 2
  • 7

4 Answers4

5

You couldn't assign a value to a method like that, even if it were accessible. You need to subscribe to the event:

btn.Click += ClickHandlingMethod;
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
4

An example:

private void CreateAButton()
{
    var button = new ImageButton();
    button.ImageUrl = "yourimage.png";
    button.ID = "Button1";
    button.Click += ButtonClick;

    Page.Form.Controls.Add(button);
}

private void ButtonClick(object sender, ImageClickEventArgs e)
{
    // Do stuff here
    // ...
}
Christophe Geers
  • 8,564
  • 3
  • 37
  • 53
4

Take a look at this answer, it is related with dynamic controls and events

As Jon commented you cannot add a string to the event, in this case you need to add a handler for the event:

    protected void Page_Init(object sender, EventArgs e)
    {
        var i = new ImageButton();
        i.Click += new ImageClickEventHandler(i_Click);
        this.myPanel.Controls.Add(i);
    }

    void i_Click(object sender, ImageClickEventArgs e)
    {
        // do something
    }

Alternativeley

    protected void Page_Init(object sender, EventArgs e)
    {
        var i = new ImageButton();
        i.Click += (source, args) =>
        {
            // do something
        };
        this.myPanel.Controls.Add(i);
    }
Community
  • 1
  • 1
Jupaol
  • 21,107
  • 8
  • 68
  • 100
  • Lambdas for this has a bad code smell. I would encourage the use of a named function. – jcolebrand Jun 16 '12 at 08:34
  • @jcolebrand: Why? If there's only a small amount of code here which doesn't need to be called from anywhere else (e.g. it may just call a method with a more suitable signature) I see nothing wrong with using a lambda here. – Jon Skeet Jun 16 '12 at 10:07
  • Note that I didn't mention adding strings to events - I said that the OP was trying to assign a value (which happened to be a string, but that's actually irrelevant) to a *method*. – Jon Skeet Jun 16 '12 at 10:07
  • Oh, there's nothing inherently _wrong_ with it @JonSkeet but by the same token I would encourage the use of a named function in javascript instead of an inline clickhandler. – jcolebrand Jun 16 '12 at 10:35
  • @jcolebrand: Why? If it's just doing one simple thing, then keeping it at the point of subscription: a) means you can see exactly what it's doing; b) doesn't "pollute" the rest of the class with a method you don't want to use from anywhere else. If there are legitimate reasons for having it separate - e.g. testing - then that's a different matter, but I certainly don't think it's a "bad code smell". – Jon Skeet Jun 16 '12 at 11:34
  • For the same reason people say that the use of ternary is a bad code smell (something I don't have an issue with, fwiw). In this particular case, it tickles my code-nose. I never said I had to be right (and I know you didn't either), I was just trying to encourage someone who already doesn't understand "I'm assigning a string and it's not working" for event handler subscription to stick to something with a little less "advanced-ness". I get that lambdas aren't really "advanced", but they're harder for some people to understand immediately. Named functions are generally more accessible here. – jcolebrand Jun 16 '12 at 11:41
  • @jcolebrand what I hear from you is more like a rigid rule which doesn't have a solid base, lambdas are perfectly valid to use in this context, I would try to avoid them if the event body is too big otherwise, the use of lambdas I consider it easier to read. Now if you have found yourself avoiding lambdas because of this reason, then I would say it's a problem with your design and you would be violating the SRP which is worst. So my advise would be focus on the design first and based on that take the correct decision. – Jupaol Jun 16 '12 at 20:42
  • That, my good sir, is why they call it a "smell", because it changes by usage scenario. In some places it's a great concept, and in others it isn't. I'm not sure where you got "rigid rule". I think you need to revisit `btn.OnClick = "someMethod";` and technical merit of solutions based around non-named functions for people who don't understand event subscription in the first place. I never said don't use inline anonymous functions, I use them from time to time _where appropriate_, but I don't use them over all other forms, and by the same token, I use named functions where appropriate. – jcolebrand Jun 16 '12 at 21:19
0

You can use this code (one significant change) :

private void CreateAButton()
    {
        var button = new ImageButton();
        button.ImageUrl = "yourimage.png";
        button.ID = "Button1";           
        button.PostBackUrl = "http://www.towi.lt";
        Page.Form.Controls.Add(button);
    }

Trick is in "PostBackUrl". If you write correct link it will redirects to it (as in example). In other cases this will add original server name, '/' and text you entered. For example 'xxx' will be turned to "http://yourservername/xxx". It is very useful, when you working with redirects to same ISS, but different sites and dynamically creating buttons for users.