Это происходит потому, что значение i
не отображается на странице (как это было бы в MVC / Razor Pages), оно просто оценивается, когда вы запускаете событие. Вы не активируете событие, пока страница не будет отрисована, поэтому к этому моменту l oop будет завершено, поэтому значение для i
всегда будет значением в конце l oop.
Есть несколько способов справиться с этим: либо используйте вместо него foreach
l oop, если это подходит (что и делается в большинстве примеров документации Blazor), либо объявите локальную переменную внутри l oop:
@for(int i=0;i< ListData.DataView.Table.Rows.Count; i++)
{
int local_i=i;
// Now use local_i instead of i in the code inside the for loop
}
Здесь хорошее обсуждение этого в репозитории Blazor Docs , которое объясняет проблему следующим образом:
Проблема обычно встречается в обработчиках событий и выражениях привязки. Мы должны объяснить, что в for
l oop у нас есть только одна итерационная переменная, а в foreach
у нас есть новая переменная для каждой итерации. Мы должны объяснить, что содержимое HTML отображается при выполнении for
/ foreach
l oop, но обработчики событий вызываются позже. Вот пример кода, демонстрирующий одно неправильное и два хороших решения.
Все это особенно сбивает с толку, если вы переходите в Blazor из фона страницы MVC / Razor, где for
- это нормальное поведение. Разница в том, что в MVC значение i
фактически записывается в html на странице, и поэтому будет отличаться для каждой строки таблицы в вашем примере.
Согласно проблема, указанная выше, и ответ @Fat Man No Neck, причина root заключается в различиях в поведении циклов for
и foreach
с лямбда-выражениями. Это не ошибка Blazor, просто C# работает.