我有一个程序,可以在图表中添加一系列“blips”:
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);
>如何清除使用此代码创建的所有“blip”按钮?
>当名称等于某个呼号时,有没有办法改变blip的背景颜色?每个blip都与ListBox中的选择相关联,我想在用户选择它时更改blip的颜色.
解决方法
每个人都忘记了一个非常重要的细节:你必须Dispose()控件或它将永远泄漏:
for (int ix = this.Controls.Count - 1; ix >= 0; ix--) { if (this.Controls[ix] is PictureBox) this.Controls[ix].Dispose(); }
我将更多地强调forever子句,在注释中有很多关于它的喧嚣,Control类的行为与其他.NET类不同.控件通过其Handle属性保持活动状态.哪个存储本机Windows句柄.只要存在本机窗口,就无法销毁Control对象.
这需要在使用Clear()或Remove()并从其父级删除控件时人工保持对象. Winforms使用所谓的“停车窗口”作为此类控件的主机.它是一个像任何其他窗口一样的普通本机窗口,它只是不可见.它的工作是成为这种孤立控制的父母.
停车窗口允许在Windows中通常很难做到的许多巧妙的技巧.例如,您可以在运行时打开和关闭ShowInTaskbar属性.窗口的属性,通常只能在创建窗口时指定(WS_EX_APPWINDOW样式,在CreateWindowEx()调用中指定). Winforms甚至可以在您创建窗口后通过将窗体的控件移动到停放窗口,破坏窗口,再次创建窗口并将控件移回原来来完成.整齐.
但是,如果您删除控件并且不调用其Dispose()方法,那么这个答案的主题就是不那么整洁,那么它将继续在停车窗口生存.永远.一个真正的泄漏.垃圾收集器无法对其做任何事情,它会看到对象的有效引用.严重违反IDisposable合同,调用Dispose()是可选的,但它不适用于Control类.
幸运的是,这样的错误很容易诊断,它不需要任何特殊工具,您可以在任务管理器的进程选项卡中看到泄漏.添加“USER Objects”列.