Tworzenie eventów w pętli

0

Witam serdecznie, mam taki kod:


ToolStripMenuItem []elementy;

private void Form1_Load(object sender, EventArgs e)
{
    elementy= new ToolStripMenuItem[10];

            for (int i = 0; i < elementy.Length; i++)
            {
                 // jakiś kod

                EventHandler nowy_event = (object from, EventArgs args) =>
                {
                      MessageBox.Show(i.ToString());
                };

                elementy[i].Click += nowy_event;

            }
}

Tylko teraz po kliknięciu na daną pozycje w menu zawsze w messageboxie wyświetla mi się ta sama liczba, nie zależnie od tego w jaki element kliknę. Co jest nie tak?

Z góry dziękuje za pomoc

P.S. Tablica eventów też nic nie zmienia :(

1

spróbuj tak:

            for (int i = 0; i < elementy.Length; i++)
            {
                 // jakiś kod

                int ii = i;
                EventHandler nowy_event = (object from, EventArgs args) =>
                {
                      MessageBox.Show(ii.ToString());
                };

                elementy[i].Click += nowy_event;

            }
0

Super działa. Dzięki wielkie. Mógłbyś mi jeszcze wyjaśnić dlaczego to i trzebabyło przypisać do nowej zmiennej? :)

1

Bo lambda odwołuje się zawsze do prawdziwej zmiennej, a nie do wartości (można to sobie wyobrazić jako przyjmowanie zmiennych przez referencję).

Tak złapana zmienna przedłuża swoją żywotność do czasu życia lambdy — więc wyjście z pętli for powoduje, że jej licznik int i wcale nie ginie, tylko żyje dalej w lambdach. Ponieważ jego ostateczna wartość jest równa elementy.Length, bo tyle wynosi w momencie końca pętli, to jest to właśnie wartość, którą widzisz w każdej lambdzie.

Użycie niby bezsensownego int ii = i powoduje, że za każdym przebiegiem pętli jest łapane inne ii, z inną przypisaną mu wartością.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0