在C#中动态创建PictureBox数组的Click事件

时间:2016-08-04 05:38:46

标签: c# winforms event-handling picturebox eventhandler

我想帮助解决这段代码问题。下面的方法应该发送一个字符串" selectedFilePath'到第二种形式' f2'每当单击PictureBox时。我有一个Picturebox数组,每个人都需要向第二个表单发送不同的字符串。我遇到的问题是每次都发送相同的字符串。 vidFilePaths是一个存储文件路径的字符串数组。 PictureBox的数组是动态创建的。

public void launchMovie(PictureBox[] pics, string[] vidFilePaths)
    {
        for (int i = 0; i < p-1; i++)
        {
            pics[i].Click += (sender, EventArgs) =>
            {
                selectedFilePath = "file:///" + vidFilePaths[i];
                Form2 f2 = new Form2(selectedFilePath);
                this.Hide();
                f2.Show();
            };
        }
    }

3 个答案:

答案 0 :(得分:1)

您需要使用局部变量来存储i,否则所有事件都会在方法结束时指向相同的值(p):

public void launchMovie(PictureBox[] pics, string[] vidFilePaths)
{
    for (int i = 0; i < p - 1; i++)
    {
        int currentIndex = i;
        pics[i].Click += (sender, EventArgs) =>
        {
            selectedFilePath = "file:///" + vidFilePaths[currentIndex];
            Form2 f2 = new Form2(selectedFilePath);
            this.Hide();
            f2.Show();
        };
    }
}

您需要了解当匿名方法捕获局部变量(Closure)时,该变量存储在编译器创建的类中。这样做是为了在方法launchMovie返回后保留该值。因此,所有事件实际上都访问托管堆中的相同内存地址,这是实际点击的时间,并且事件被引发为i = p

简而言之,当您单击时,方法launchMovie将结束并且i = p,此值将存储在编译器生成的类中并由事件使用。

尝试在单独的方法中创建事件,看看如何存储i的值以便使用它,您将了解编译器正在做什么。

替代:

作为替代方案,您可以使用pics[i].Tag像这样:

public void launchMovie(PictureBox[] pics, string[] vidFilePaths)
{
    for (int i = 0; i < p - 1; i++)
    {
        pics[i].Tag = vidFilePaths[i];
        pics[i].Click += (sender, EventArgs) =>
        {
            int index = 
            selectedFilePath = "file:///" + pics[i].Tag.ToString();
            Form2 f2 = new Form2(selectedFilePath);
            this.Hide();
            f2.Show();
        };
    }
}

答案 1 :(得分:0)

解决方案:

public void launchMovie(PictureBox[] pics, string[] vidFilePaths)
    {
        int i = 0;
        for (i = 0; i < p-1; i++)
        {
            pics[i].Tag = i;
            pics[i].Click += (sender, EventArgs) =>
            {
                int k = Convert.ToInt32((sender as PictureBox).Tag);
                Form2 f2 = new Form2("file:///" + vidFilePaths[k]);
                this.Hide();
                f2.Show();
            };
        }
    }

答案 2 :(得分:-1)

当您动态创建PictureBox时,您必须为其指定名称并在此处绑定事件,如

for(int i=0; i<yourCount; i++)
{
  PictureBox pic=new PictureBox();
  pic.Name=i.ToString();
  pics.Click += PickClicked;
}

并像这样更改事件处理程序中的功能

private void PickClicked(object sender, EventArgs e)
{
   PictureBox picBox= sender as PictureBox;
   string selectedFilePath = "file:///" + vidFilePaths[Convert.ToInt(picBox.Name)];
   Form2 f2 = new Form2(selectedFilePath);
   this.Hide();
   f2.Show();
}

希望它有所帮助!!!