我们有Lights out Game来编程
Button[,] lights = new Button[5,5];
for (int i = 0; i < lights.GetLength(1); i++)
{
for (int j = 0; j < lights.GetLength(0); j++)
{
lights[i, j] = new Button();
lights[i, j].Size = new System.Drawing.Size(50, 50);
lights[i, j].Click += (sender, args) => light_OnOff(lights[i,j], i, j);
lights[i, j].BackColor = Color.Yellow;
lightPanel.Controls.Add(lights[i, j]);
MessageBox.Show("I:"+Convert.ToString(i) + "J:" +Convert.ToString(j));
}
}
}
public void light_OnOff(object sender, int i, int j)
{
if(lights[i, j].BackColor == Color.Yellow)
{
lights[i, j].BackColor = Color.Black;
}
}
}
}
我现在遇到的问题是它表示它超出Array
范围(索引),但我不知道为什么。也许你可以帮助我。
答案 0 :(得分:1)
不要按照自己的方式创建活动,而是设置按钮的名称以将它们彼此分开。
for (int i = 0; i < lights.GetLength(1); i++)
{
for (int j = 0; j < lights.GetLength(0); j++)
{
lights[i, j] = new Button();
lights[i, j].Size = new System.Drawing.Size(50, 50);
lights[i, j].Name = "button" + i.ToString() + j.ToString(); // set name like this
lights[i, j].Click += autoGeneratedEventName_Click; //after "+=" hit tab twice visual studio will create event auto;
lights[i,j].Location = new Point(40 + (j*70), 20 + (i * 70));
lights[i, j].BackColor = Color.Yellow;
this.panel1.Controls.Add(lights[i, j]);
//MessageBox.Show("I:" + Convert.ToString(i) + "J:" + Convert.ToString(j));
}
}
在活动中,发件人将解决问题,您不需要将数组索引发送到事件。 (你也可以找到最后2个名字的按钮索引)
private void autoGeneratedEventName_Click(object sender, EventArgs e)
{
Button b = sender as Button; //Clicked object is a Button
if (b.BackColor == Color.Yellow)
{
b.BackColor = Color.Black;
}
label1.Text = b.Name;
}
结果;
希望有所帮助,
答案 1 :(得分:0)
你正在处理一个所谓的&#34;关闭&#34;在你的代码中。
lights[i, j].Click += (sender, args) => light_OnOff(lights[i,j], i, j);
变量i&amp; j不是由lamdba表达式复制的,而是作为引用处理,在这些循环结束后仍然存在。因此,当触发点击事件时,它会使用i&amp;的最新值。 j(5),导致超出数组范围异常。
要获得预期的行为,您可以复制i&amp; j到局部变量,如下:
int e = i; int f = j;
lights[i, j].Click += (sender, args) => light_OnOff(lights, e, f);
阅读本文以获取更多信息:http://csharpindepth.com/Articles/Chapter5/Closures.aspx