为什么 UserControl 的 Unloaded 事件不会触发?

Why the Unloaded event of UserControl would not fire?

我刚刚在我正在开发的一个简单的 Windows 商店应用程序中发现了巨大的内存泄漏。

事实证明,我在 ListView 的 ItemTemplate 中放置了一个 UserControl,并挂钩了 UserControl 的 Unloaded 事件以分离一些事件处理程序。

我预计当 ListView 的项目被清除 时,UserControl 的Unloaded 事件会触发,但它不会!但是当我 一个一个地删除 项目时,UserControl 的 Unloaded 事件将按预期触发。

任何人都可以给我一些建议吗?或者除了挂钩 Unloaded 事件之外,我应该把清理代码放在哪里。任何想法将不胜感激!谢谢!下面是代码片段:

为了简化,ListView的ItemTemplate是:

 <DataTemplate>
      <local:MyUserControl1 />
 </DataTemplate>

MyUserControl1 只是一个空的 UserControl:

public sealed partial class MyUserControl1 : UserControl
{
    public MyUserControl1()
    {
        this.InitializeComponent();
        this.Unloaded += MyUserControl1_Unloaded;
    }

    private void MyUserControl1_Unloaded(object sender, RoutedEventArgs e)
    {
        Debug.WriteLine("MyUserControl1_Unloaded...");
    }
}

默认的ListView会启用UI虚拟化。当你调用Clear()方法时,ListView会做一些特殊处理,它实际上并没有移除这些项目(我相信你也发现了这种情况)。

您可以在实时可视化树中看到ListView 的ActualHeight(设置为0)。这就是为什么您在 UI.

上看不到列表视图的原因

所以解决方法是使用Remove()方法或listview.Itemsource=null。您也可以尝试禁用 UI 虚拟化。例如,使用 StackPanel 作为 ItemsPanelTemplate。