2016-09-16 33 views
1

我々はライツアウトC#の多次元配列

 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

どのラインで例外がスローされますか?とにかく、デバッガを使用するときに問題を簡単に取得し、 'i'と' j'が何であるかを調べるべきです。 – HimBromBeere

+0

"light_OnOff"メソッドを開始するときに表示される "ライトボタン"をクリックすると例外が表示されます –

+0

メソッドをデバッグしましたか? – sachin

答えて

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

結果;

enter image description here

希望はあなたがあなたのコードでは、いわゆる "閉鎖" を扱っている、

+0

ええ、それは多くの感謝を助け、今私はちょうど一度に十字を "無効にする"方法を理解する必要があります。 –

+0

イベントにelseステートメントを追加するだけで大​​したことではありません。 @RonAmme – Berkay

0

に役立ちます。

lights[i, j].Click += (sender, args) => light_OnOff(lights[i,j], i, j); 

変数は、私& jはlamdba式によってコピーされますが、これらのループが終了した後も存在する参照、として扱われていません。したがって、クリックイベントがトリガされると、最新の値であるi & j(5)が使用され、配列範囲外の例外が発生します。

が期待される動作を取得するには、このように、ローカル変数iに& 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