为多个按钮注册一个点击事件并为每个按钮传递不同的值

Registering one click event for multiple buttons and passing a different value per button

我根据列表中的内容程序生成按钮,该列表包含文件路径。我需要每个按钮使用以下路径从路径中打开特定文件: System.Diagnostics.Process.Start(filePath)

但是,button.Click = 要求它运行的函数是 System.EventHandler,而打开文件的代码是 System.Diagnostics.Process

下面是生成按钮的代码:

 private int importButtonFactory()
    {
        int numberOfButtons = 0;

        int top = 70;
        int left = 100;

        foreach (Import import in ImportList)
        {
            Button button = new Button();
            button.Left = left;
            button.Top = top;
            this.Controls.Add(button);
            top += button.Height + 2;
            numberOfButtons++;
            button.Text = import.Scheme;
            button.Click += openFile_Click(import.Path);
        }

        return numberOfButtons;
    }

button.Click"openFile_Click()"的函数:

        private void openFile_Click(string filePath)
        {
            System.Diagnostics.Process.Start(filePath);
        } 

这是我最初认为可以简单工作的方法,但是前一个函数中的函数抱怨错误:"Cannot implicitly convert type 'void' to 'System.EventHandler'"如果我使该类型的函数尝试并取悦,它说该函数不起作用return 任何值....我不希望它这样做,但 System.EventHandler 似乎需要它。

我不确定是否有任何虚拟数据我可以得到它 return 因为 System.EventHandler 只是为了闭嘴,或者有一个我不知道的正确方法让我的场景工作。

编辑:这是一个 Windows 表格申请

您可以使用 lambda expression 来做这样的事情:

button.Click += (object sndr, EventArgs c_args) => openFile_Click(import.Path);

此代码有效。但是,编译器会警告您正在访问闭包中的 foreach 循环变量 (import)。要解决此问题,请像这样创建一个局部变量:

var path = import.Path;

button.Click += (object sndr, EventArgs c_args) => openFile_Click(path);

您的事件处理程序必须与事件签名匹配。所以你的按钮点击处理程序必须使用这个签名:

private void Button_Click(object sender, System.EventArgs e)
{
}

现在要识别哪个URL属于哪个按钮,你可以给按钮一个标签,例如持有列表索引,假设它是一个List<T>或另一个可索引的集合:

    for (int i = 0; i < ImportList.Count; i++)
    {
        // ...
        button.Text = ImportList[i].Scheme;
        button.Tag = i;
        button.Click += Button_Click;
    }

然后在您的点击处理程序中:

private void Button_Click(object sender, System.EventArgs e)
{
    Button button = sender as Button;
    int index = (int)button.Tag;

    var import = ImportList[index];

    Process.Start(import.Path); 
}