Удаление динамически созданных элементов управления в C #

У меня есть программа, которая добавляет серию «блипов» к графику:

PictureBox blip = new PictureBox(); blip.Location = new Point(blipHours, blipAltitude); blip.Size = new Size(6, 6); blip.BackColor = System.Drawing.Color.Lime; blip.Text = ""; blip.Name = callsign; this.Controls.Add(blip); this.Controls.SetChildIndex(blip, 0); 
  1. Как у меня есть кнопка очистить все «блики», которые были созданы с помощью этого кода?

  2. Есть ли способ изменить цвет фона на экране, когда его имя равно определенному callsign ? Каждая ошибка связана с выбором в ListBox , и я хотел бы изменить цвет blip, когда пользователь его выбирает.

Все забывают очень важную деталь: вам нужно Dispose () контролировать или он просочится навсегда:

 for (int ix = this.Controls.Count - 1; ix >= 0; ix--) { if (this.Controls[ix] is PictureBox) this.Controls[ix].Dispose(); } 

Я добавлю еще один акцент на предложение forever , в комментариях много шума, class Control не ведет себя как любой другой class .NET. Элемент управления сохранен в соответствии с свойством Handle . В котором хранится собственный дескриптор Windows. Пока существует собственное окно, объект Control не может быть уничтожен.

Это требует, чтобы объект поддерживался искусственно, когда вы используете Clear () или Remove () и удаляете элемент управления из его родителя. Winforms использует так называемое «парковочное окно» в качестве узла таких элементов управления. Это нормальное собственное окно, как и любое другое, оно просто не видно. Его задача – быть родителем таких сиротских контролей.

Окно парковки допускает множество аккуратных трюков, которые обычно очень сложно сделать в Windows. Вы можете, например, включить и отключить свойство ShowInTaskbar во время выполнения. Свойство windows, которое обычно можно указывать только при создании windows (стиль WS_EX_APPWINDOW, указанный в вызове CreateWindowEx ()). Winforms могут сделать это даже после создания windows, перемещая элементы управления формы в окно парковки, уничтожая окно, создавая его снова и перемещая элементы управления обратно. Ухоженная.

Но с не очень аккуратным зависанием, который является темой этого ответа, если вы удалите элемент управления и не вызываете его метод Dispose (), он продолжит выживать в окне парковки. Навсегда. Истинная утечка. Ничто из того, что сборщик мусора не может сделать с этим, видит правильную ссылку на объект. Довольно грубое нарушение договора IDisposable, вызывающего Dispose (), является необязательным, но оно не относится к classу Control.

К счастью, такая ошибка довольно легко диагностируется, она не требует каких-либо специальных инструментов, вы можете увидеть утечку на вкладке «Процессы менеджера задач». Добавьте столбец «USER Objects».

 this.Controls.Clear(); 

Возможно, вы захотите добавить спам в список, а затем, когда пользователь нажмет кнопку «Очистить», просто перейдя по списку, удалите всплывающее окно из коллекции «Элементы управления», а затем очистите список.

Что касается изменения цвета фона, почему бы вам просто не использовать оператор if?

 blip.BackColor = callsign == "SpecialSign"? System.Drawing.Color.Red : System.Drawing.Color.Lime 

Это приведет к удалению всех элементов управления PictureBox из конкретного контейнера (я предполагаю график в вашем случае).

  for (int i = this.Controls.Count - 1; i >= 0; i--) { PictureBox control = this.Controls[i] as PictureBox; if (control == null) continue; control.Dispose(); } 

Кажется, Ханс Пассант тоже забыл очень важную деталь (или, может быть, он просто добавлял к существующим ответам, не отправляя полный ответ). Во всяком случае, вот что я должен был сделать для того, чтобы invisiblize и избавиться от своих динамических элементов управления:

 Panel p = tp.Controls[panelName] as Panel; p.Controls.Clear(); for (int i = 0; i < p.Controls.Count; i++) { p.Controls[i].Dispose(); } 
Давайте будем гением компьютера.