我有以下代码:
public void LoadPage()
{
LayoutPanel.Controls.Clear();
ContentObjects = LoadContentObjects();
foreach (string img in ContentObjects)
{
thumbnail = new ctrlThumbnailControl(img);
LayoutPanel.Controls.Add(thumbnail);
thumbnail.ThumbnailSelected += Thumbnail_ThumbnailSelected;
}
}
private void Thumbnail_ThumbnailSelected(string PathToMedia)
{
lblFileName.Text = PathToMedia;
}
我为加载的每个图像创建一个缩略图控件(每页限制为 150 个)。缩略图控制器具有一个事件,该事件在悬停在控件上时引发。
因此,此页面有 150 个带有事件的控件。当我加载下一页时,我不会删除事件。我确实删除了控件。并创建另外 150 个控件,向其添加事件。
所以问题是:
- 当控件被清除()时,事件处理程序是否被删除?
如果不是,我将如何以编程方式清除事件处理程序,而无需单独遍历每个控件并删除其处理程序?
你正在做的事情是安全的,因为你扔掉的东西是保存引用的东西。 也就是说,每个Control
都保存对委托的引用,该委托保存对具有事件处理程序的对象(通常是 Form
或其他一些长期对象)的引用,但具有事件处理程序的对象在从 UI 中删除控件后不保留对控件的引用。 Control
变得完全无法访问(假设您没有出于其他目的持有对它的引用),因此它仍然"知道"长寿命对象是无关紧要的。 当垃圾回收器运行时,Control
将消失,委托将随之消失。
另一方面,您不想做的是将短期对象注册为长期对象的事件处理程序(而不记得取消注册)。 当你这样做时,即使你认为你已经"删除"了短生存期的对象,长生存期对象仍然知道这个短生存期的对象,这使得它永远不会被垃圾回收,并且你拥有本质上是内存泄漏的托管内存版本(更不用说现在应该断开连接的对象仍将响应事件)。
如果控件不可见,则无法从 GUI 触发事件。无需分离事件。它们不会造成任何"伤害"。