简体   繁体   English

如何正确地将事件分配给 c# Winforms 中动态创建的按钮?

[英]How to properly assign events to dynamically created buttons in c# Winforms?

My intention is to create buttons at runtime and have a click event handler subscribed to them.我的意图是在运行时创建按钮并订阅它们的点击事件处理程序。 Once the dynamically created button is clicked, the click eventhandler is unsubscribed, such that the click event only fires once.一旦点击了动态创建的按钮,点击事件处理程序就会被取消订阅,这样点击事件只会触发一次。

At runtime the desired behaviour only works if I create one button and click it immediately.在运行时,仅当我创建一个按钮并立即单击它时,所需的行为才有效。 If I create more than one button, than only the last created button unsubscribes from the click event.如果我创建了多个按钮,那么只有最后一个创建的按钮会取消订阅 click 事件。 Did I miss something?我错过了什么?

public partial class Form1 : Form
{
    Button b;
    int counter;

    public Form1()
    {
        InitializeComponent();
    }

    // create more buttons
    private void button1_Click(object sender, EventArgs e)
    {
        b = new Button();
        b.Size = new Size(50, 50);
        b.Click += b_Click; // dynamic button click event
        this.Controls["flowLayoutPanel"].Controls.Add(b);

    }

    // dynamic button click eventhandler
    void b_Click(object sender, EventArgs e)
    {
        b.Text = counter.ToString();
        b.Click -= b_Click;
        counter++;
    }
}

Because b member will reference last created dynamic button, so clicking any buttons will remove click event handler of currently referenced button in b variable, which would be last created.因为b成员将引用最后创建的动态按钮,所以单击任何按钮将删除b变量中当前引用的按钮的单击事件处理程序,这将是最后创建的。

Use sender to access instance of "current" button and remove click event handler only from "current" button.使用sender访问“当前”按钮的实例并仅从“当前”按钮中删除单击事件处理程序。

void b_Click(object sender, EventArgs e)
{
    var button = sender As Button;
    button.Text = counter.ToString();
    button.Click -= b_Click;
    counter++;
}

Don't use private member for dynamic button, but local variable不要将私有成员用于动态按钮,而是使用局部变量

private void button1_Click(object sender, EventArgs e)
{
    var button = new Button();
    button.Size = new Size(50, 50);
    button.Click += b_Click;
    this.Controls["flowLayoutPanel"].Controls.Add(button);
}

If you need to reference collection of created button somewhere, you can access them from the controls of flow panel where buttons were added如果您需要在某处引用已创建按钮的集合,您可以从添加按钮的流程面板的控件中访问它们

var dynamicButtons = . 
    this.Controls["flowLayoutPanel"].Controls.OfType<Button>().ToList();

Or save them to the dedicated collection (in case flow panel has other buttons)或者将它们保存到专用集合中(如果流面板有其他按钮)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM