0

What I try to achieve is, that I first generate some buttons dynamically via a loop and then give each button its own click action, in C#.

But unfortunately only the last click event will be executed for all buttons. (Every button will print "Klick - 3")

How can I achieve that each button will print e.g. its own message?

So, when I click Button-0 it will display "Klick - 0", and so on.

Here a simple example:

public static void Main(string[] args){

    Form form = new Form();
    form.Location = new System.Drawing.Point(0,0);
    form.Width = 300;
    form.Height = 300;
    
    List<Button> buttons = new List<Button>();
    
    for(int i = 0; i < 3; i++)
    {
        buttons.Add(new Button());
        buttons[i].Text = $"Button - {i}";
        buttons[i].Location = new System.Drawing.Point(0,i*40);
        form.Controls.Add(buttons[i]);
    }
    
    for(int i = 0; i < 3; i++)
    {
        buttons[i].Click += (s,e) => 
        {
            Console.WriteLine($"Klick - {i}");
        
        };
    }
    
    // keeps the form from disappearing
    Application.Run(form);
    

}

I also thought maybe I could put all those events separately into some event-list(?), so they could be executed from there, but no luck with that.


PS: I found out, I could put something like:

if(s==buttons[0])

into the Click-Event-Loop and continue with some else-ifs to have each button its own actions, but isn't there something more convenient? I mean everytime the click event is triggered it would have to cycle through all the ifs...

Gubbel
  • 1
  • 1
  • is this your question? `Event binding on dynamically created elements?` – Nadeem Taj Oct 24 '21 at 18:27
  • 1
    The problem is, the lambda expression used for the event handler is catching the for-variable by reference. So at the time the buttons get clicked, `i` will have the value of 3, regardless which event handler gets invoked. The simple solution would be to declare a variable in the loop and use its value (which doesn't change like `i`), say `var j = i;` as the first line in the for-loop and use `j` in Console.WriteLine(...). – Steeeve Oct 24 '21 at 18:46
  • NadeemTaj Do you mean that one?: [Link](https://stackoverflow.com/q/203198) No, I think not. I have never done something with javascript / jQuery, so I have difficulties to see what is meant there, but it seems similar be to my question. Thanks. @Steeeve Thank you, this works, when I generate the variable j = i in the first line of for. But I don't really understand why it works. Both i and j are declared in the for-loop and should have the same value at any time, isn't it? I can't seem to understand the difference... – Gubbel Oct 24 '21 at 21:06
  • You can find some explanations [here](https://stackoverflow.com/questions/451779/how-to-tell-a-lambda-function-to-capture-a-copy-instead-of-a-reference-in-c) – Steeeve Oct 24 '21 at 22:39
  • @Steeeve Thank you, those answers there were very useful, the topic is still a bit confusing to me, though. But anyway, thank you very much for that link. – Gubbel Oct 26 '21 at 19:09

0 Answers0