2014-01-19 3 views
0

Я динамически создаю список CommandLink controls и добавляю их в панель. Я создал метод удаления всех элементов управления CommandLink с панели, и он работает по большей части, за исключением того, что он только удаляет все остальные элементы управления. Если я снова вызову метод, он сделает то же самое с остальными элементами управления только для удаления всех остальных. Может ли кто-нибудь сказать мне, где я ошибаюсь? Конструктивная критика также приветствуется.Control.Remove удаляет только все остальные элементы управления

private void MainMenu_Load(object sender, EventArgs e) 
    { 
#if DEBUG 
     // Generate dummy actions 
     for (int i = 0; i < 20; i++) 
     { 
      CommandLink cl = AddCommandLink(String.Format("cl{0}",i), String.Format("Command #{0}", i), "The quick brown fox jumps over the lazy dog.", true); 
      cl.Click += new EventHandler(CommandLinks_Click); 
     } 
#endif 
    } 

    private void CommandLinks_Click(object sender, EventArgs e) 
    { 
     ClearCommandLinks(); 
    } 

    private CommandLink AddCommandLink(string name, string text, string note = "", bool shield = false) 
    { 
     int top = 0; 
     foreach (Control c in splitMain.Panel2.Controls) 
      if (c.GetType() == typeof(CommandLink)) 
       top = Math.Max(top, ((CommandLink)c).Bottom); 
     CommandLink cl = new CommandLink(); 
     cl.Name = name; 
     cl.Location = new Point(10, top + 10); 
     cl.Width = splitMain.Panel2.ClientSize.Width - SystemInformation.VerticalScrollBarWidth - 20; 
     cl.Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right; 
     cl.Text = text; 
     if (!String.IsNullOrEmpty(note)) 
      cl.Note = note; 
     if (shield) 
      cl.Shield = true; 
     splitMain.Panel2.Controls.Add(cl); 
     return cl; 
    } 

    private void ClearCommandLinks() 
    { 
     foreach (Control c in splitMain.Panel2.Controls) 
     { 
      if (c.GetType() == typeof(CommandLink)) 
      { 
       CommandLink cl = (CommandLink)c; 
       splitMain.Panel2.Controls.Remove(cl); 
      } 
     } 
    } 
+1

вы нарушаете кардинальное правило 'foreach' - вы никогда не должны пытаться изменить коллекцию вы перечисляющий более. иногда вы получаете странное поведение, иногда вы получаете исключение, редко это «просто работает» –

ответ

3

Попробуйте не вынимая из списка вы пересекающие.

сделать это:

List<Control> removeList = new List<Control>(); 
foreach (Control c in splitMain.Panel2.Controls) 
{ 
    if (c.GetType() == typeof(CommandLink)) 
    { 
     removeList.Add(c); 
    } 
} 

foreach(Control c in removeList) 
{ 
    splitMain.Panel2.Controls.Remove(c); 
} 
0

Я думаю, что изменение коллекции, как вы итерации, является проблемой.

Попробуйте цикл:

for (int index = 0; index < splitMain.Panel2.Controls.length... 
+0

Это, похоже, приводит к такому же поведению. –

+0

@druciferre: Не указывайте '++ index', когда вы удаляете –

+0

, если вы собираетесь делать цикл for, сделайте это в обратном порядке. –

Смежные вопросы