Jakob Danielsson
Jakob Danielsson

Reputation: 787

Capture the right button click event

I'm playing around abit with winforms and its controls and just discovered how to do custommade buttonclicks. However, there is a problem. I've got a loop, that's looping through a list of elements, and if a condition appears - I'm creating a button that will pop up a gridview.

public void draw(ref Panel inputPanel) //draws the eventline
    {
        int stepCounter = 0;
        for (int i = 0; i < DaysList.Count-1; i++)
        {
            Button b1;
            if (DaysList[i].Elements.Count > max)
            {
                b1 = new Button(); //Create the box
                b1.Width = 120;
                b1.Height = 40; //Set width and height
                b1.Location = new Point(stepCounter + 35, 70); //Location
                inputPanel.Controls.Add(b1); //
                b1.Text = "Check event date in grid";
                b1.Show();
                b1.BringToFront();
                b1.Click += new EventHandler((sender, e) => btn_Click(sender, e, DaysList[i].Elements));
                stepCounter += 200;
            }
         }
     } 

That was my method for creating the buttons and a click event for the when my condition appears. The function that is passed to the eventhandler looks like this:

public void btn_Click(object sender, EventArgs e, List<EventElement> inputElems)
    {
        Button button = sender as Button;
        DataGridForm window = new DataGridForm(inputElems);
        window.Show();
    }

public class EventElement
{
     public EventElement()
     {
     }
     public int Count{get;set;}
     public string Date{get;set;}
}

The clickpart of the event is fine but whenever i click the spawned buttons, I get the wrong data into the gridview. As an example: The loop has created four buttons for me and they are presented on a straight line on the form. But whenever i click one of the buttons - dosnt matter which one of them, the button always return the data of the last spawned button. A more clear example: lets say we have the list inputElems looks like this:
inputElems[0].Count -> 2644
inputElems[1].Count -> 2131
inputElems[2].Count -> 8467
inputElems[3].Count -> 5462
When i now click the second button, the input to the second buttons parameter list should have the values (sender, e, 2131), right? but for some reason, the last argument gets the same like the 4th element in the list, even though i call the secondly created button.

I figured that it has something to do with me always calling the last added button_click to the eventhandler of the button, if so, how do I call different clicks from the EventHandler?

Upvotes: 1

Views: 311

Answers (2)

Mike Perrenoud
Mike Perrenoud

Reputation: 67918

The problem is that the for loop is out of scope, and thus unable to provide you with the data you're looking for. A more straight forward approach might be something like this:

public void draw(ref Panel inputPanel) //draws the eventline
{
    int stepCounter = 0;
    for (int i = 0; i < DaysList.Count-1; i++)
    {
        Button b1;
        if (DaysList[i].Elements.Count > max)
        {
            b1 = new Button(); //Create the box
            b1.Width = 120;
            b1.Height = 40; //Set width and height
            b1.Location = new Point(stepCounter + 35, 70); //Location
            inputPanel.Controls.Add(b1); //
            b1.Text = "Check event date in grid";
            b1.Show();
            b1.BringToFront();
            b1.Tag = DaysList[i].Elements;
            b1.Click += btn_Click;
            stepCounter += 200;
        }
     }
 } 

and then in btn_Click, do this:

public void btn_Click(object sender, EventArgs e)
{
    Button button = sender as Button;
    int inputElems = (List<EventElement>)button.Tag;
    DataGridForm window = new DataGridForm(inputElems);
    window.Show();
}

Upvotes: 1

Bolu
Bolu

Reputation: 8786

Instead of passing inputElems with the EventHandler, you can use Tag.

E.g. use:

b1.Tag=i;

Then in your click event handler:

public void btn_Click(object sender, EventArgs e)
    {
        Button button = sender as Button;
        DataGridForm window = new DataGridForm(DaysList[int.Parse(button.Tag.ToString())].Elements);
        window.Show();
    }

Upvotes: 1

Related Questions