Вопрос по enumeration, foreach, controls, c#, winforms – контроль foreach c # пропуская элементы управления

4

У меня есть следующий цикл для удаления кнопок в моем приложении C # Windows Forms. Единственная проблема в том, что она пропускает все остальные кнопки. Как мне удалить все элементы управления кнопками из моей формы?

foreach (Control cntrl in Controls)
{
    if(cntrl.GetType() == typeof(Button))
    {
        Controls.Remove(cntrl);
        cntrl.Dispose();
    }
}
Я не получаю никакой ошибки ни в исполнении, ни в списке ошибок. Что ты предлагаешь? Aunt Jemima
Не проверял, но я ожидаю, что этот код выдаст исключение, потому что вы не можете изменить коллекцию (Controls) пока зацикливаясь. default locale
Я обнаружил, что вопрос, поднятый @defaultlocale и другими комментаторами, уже задавался вПочему ControlCollection НЕ генерирует исключение InvalidOperationException?, Я удалил свои комментарии здесь и разместил их какответ по этому вопросу. Я ответил на этот вопрос в этом ответе, поэтому этот вопрос, по крайней мере, всегда будет отображаться в разделе «Связанные» справа для этого вопроса. BACON
Я так рад, что смог отследить этот вопрос. У меня была точно такая же проблема, и я пытался найти решение, и потребовалось некоторое время, чтобы получить правильные условия поиска. На самом деле это не выдает ошибку, даже без попытки поймать, что, я согласен, странно. Matthew Lauser
этот код выдаст исключение Invalid Operation, возможно, вы обернули бы этот код попыткой и перехватом в любом из родительских методов Sriram Sakthivel

Ваш Ответ

3   ответа
0

что вы удаляете. Используйте этот код:

    List<Control> cleanControls = new List<Control>();
    foreach(Control ctr in Controls)
    {
       if(cntrl.GetType() != typeof(Button))
       {
          cleanControls.Add(ctr);
       }
       else
       {
         ctr.Dispose();
       }
    } 
    Controls = cleanControls;

Это оно! Надеюсь, я помог!

9

var controlsToRemove = Controls.OfType<Button>().ToArray();
foreach (var control in controlsToRemove)
{
    Controls.Remove(control);
    cntrl.Dispose();
}

призваниеToArray() создает новую коллекцию бетона, так что вы можете перечислить один и изменить другой.

Это сработало отлично, и вы правы, что это очень просто. Благодарю. Aunt Jemima
2

что это не дает вам ошибок, так как вы изменяете коллекцию во время итерации по ней. Использоватьfor цикл и начать в конце:

for (int ii = Controls.Count - 1; ii >= 0; ii--)
{
    Control cntrl = Controls[ii];
    Controls.remove(cntrl);
    cntrl.Dispose();
}

(Начиная с конца, потому что в противном случае вы изменили бы индексы каждого элемента управления при выполнении итерации.)

Хм, значит, вы не можете убрать лестницу, пока стоите на ней? Спасибо за объяснение ошибки. При попытке вашего метода я получил ошибку, что не было определения для длины. Я, наверное, ошибся. Aunt Jemima
Это, вероятно.Count вместо.Length - Я не проверял код. zimdanen

Похожие вопросы