У меня есть программа, которая добавляет серию "вспышек" к графику:
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);
Как у меня есть кнопка ясной все "вспышки", которые были созданы с этим кодом?
Есть ли способ изменить цвет фона вспышки, когда его имя равно определенному callsign
? Каждая вспышка связана с выбором в a ListBox
, и я хотел бы изменить цвет вспышки, когда пользователь выбирает его.
Все забывают очень важную деталь: вам нужно Dispose () элемента управления, иначе он будет протекать вечно:
for (int ix = this.Controls.Count - 1; ix >= 0; ix--) {
if (this.Controls[ix] is PictureBox) this.Controls[ix].Dispose();
}
Я уделю больше внимания forever , много шума по этому поводу в комментариях, класс Control не ведет себя как любой другой класс .NET. Control поддерживается своим свойством Handle
. В котором хранится собственный дескриптор Windows. Пока существует собственное окно, объект Control не может быть уничтожен.
Это требует, чтобы объект поддерживался искусственно, когда вы используете Clear () или Remove () и удаляете элемент управления из его родительского элемента. Winforms использует так называемое «окно парковки» в качестве узла таких элементов управления. Это обычное родное окно, как и любое другое, просто его не видно. Его работа состоит в том, чтобы быть родителем таких осиротевших элементов управления.
Окно парковки позволяет выполнять множество изящных трюков, которые обычно очень сложно выполнить в Windows. Например, вы можете включать и выключать свойство ShowInTaskbar во время выполнения. Свойство окна, которое обычно можно указать только при создании окна (стиль WS_EX_APPWINDOW, указанный в вызове CreateWindowEx ()). Winforms может сделать это даже после того, как вы создали окно, перемещая элементы управления формы в окно парковки, уничтожая окно, создавая его снова и перемещая элементы управления назад. Аккуратный.
Но с не очень аккуратным зависанием, о котором идет речь в этом ответе, если вы удалите элемент управления и не вызовите его метод Dispose (), он продолжит работать в окне парковки. . Навсегда. Настоящая утечка. Сборщик мусора ничего не может с этим поделать, он видит действительную ссылку на объект. Довольно грубое нарушение контракта IDisposable, вызов Dispose () является необязательным, но это не для класса Control.
К счастью, такую ошибку довольно легко диагностировать, она не требует каких-либо специальных инструментов. Вы можете увидеть утечку на вкладке «Процессы» диспетчера задач. Добавьте столбец «Объекты ПОЛЬЗОВАТЕЛЯ».
Возможно, вы захотите добавить фрагмент в Список, а затем, когда пользователь нажмет кнопку "Очистить", просто провести итерацию по списку, удалить фрагмент из коллекции элементов управления, а затем очистить список.
Что касается изменения цвета фона, почему бы вам просто не использовать утверждение 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();
}