【问题标题】:How to properly assign events to dynamically created buttons in c# Winforms?如何正确地将事件分配给 c# Winforms 中动态创建的按钮?
【发布时间】:2019-10-31 03:59:45
【问题描述】:

我的意图是在运行时创建按钮并订阅它们的点击事件处理程序。一旦点击了动态创建的按钮,点击事件处理程序就会被取消订阅,这样点击事件只会触发一次。

在运行时,仅当我创建一个按钮并立即单击它时,所需的行为才有效。如果我创建了多个按钮,那么只有最后一个创建的按钮会取消订阅 click 事件。我错过了什么?

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++;
    }
}

【问题讨论】:

    标签: c# winforms events


    【解决方案1】:

    因为b 成员会引用最后创建的动态按钮,所以点击任何按钮都会删除b 变量中当前引用的按钮的点击事件处理程序,这将是最后创建的。

    使用sender 访问“当前”按钮的实例并仅从“当前”按钮中删除点击事件处理程序。

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

    动态按钮不要使用私有成员,而是局部变量

    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);
    }
    

    如果您需要在某处引用已创建按钮的集合,您可以从添加按钮的流程面板的控件中访问它们

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

    或将它们保存到专用集合中(以防流程面板有其他按钮)

    【讨论】:

      猜你喜欢
      • 2011-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      • 2011-08-21
      相关资源
      最近更新 更多