所以我有一个listview,其中包含一个包含信号图的分层数据模板。
<HierarchicalDataTemplate
DataType="{x:Type ViewModels:BusViewModel}"
ItemsSource ="{Binding Path = bits}"
>
<Components:SignalGraph
x:Name="signal_graph"
/>
如果我从itemslist中删除了一个项目,那么信号图仍然会挂在重绘事件上,所以我正在为不在屏幕上的项目重绘事件。
我的第一直觉就是去改变VirtualizingStackPanel.VirtualizationMode =“Standard” 以确保容器没有被重用,但这还不足以阻止重绘。
但是,我只是从这里使用虚拟化磁贴面板: http://blogs.msdn.com/b/dancre/archive/2006/02/16/implementing-a-virtualizingpanel-part-4-the-goods.aspx
我不认为它实现了回收。它看起来只是使用生成器的remove和generatenext方法而不是循环方法。所以我很困惑为什么生成的对象没有被正确处理掉。当我查看面板的cleanupItems方法时
private void CleanUpItems(int minDesiredGenerated, int maxDesiredGenerated)
{
UIElementCollection children = this.InternalChildren;
IItemContainerGenerator generator = this.ItemContainerGenerator;
for (int i = children.Count - 1; i >= 0; i--)
{
GeneratorPosition childGeneratorPos = new GeneratorPosition(i, 0);
int itemIndex = generator.IndexFromGeneratorPosition(childGeneratorPos);
if (itemIndex < minDesiredGenerated || itemIndex > maxDesiredGenerated)
{
generator.Remove(childGeneratorPos, 1);
RemoveInternalChildRange(i, 1);
}
}
}
我发现小组的内部孩子确实减少到1,所以我认为WPF应该为我照顾大部分内容。因此,我认为我可能需要实现IDisposable或这些行中的某些内容,以确保控件被销毁并且所有事件处理程序都已分离。
如何从属于listview的itemssource的可观察集合中删除项目时如何正确处理项目?
答案 0 :(得分:1)
你走在正确的轨道上。调用generator.Remove会从生成器缓存中删除容器,但如果项目和容器之间仍有事件或处理程序,则GC不会收集容器。
因此释放所有处理程序,wpf将负责从内存中删除容器,实际上GC会将其删除。就像你在第一句中提到的那样,你似乎有一些绘画事件。如果您不释放该事件,则容器将无法完成。
所以简单地释放你在那里的所有自定义逻辑,你应该做得很好。
答案 1 :(得分:0)
我只是挂钩了卸载的事件并解除了事件处理程序,现在代码工作正常。我在幕后猜测itemscontrol试图破坏对象,如果没有对它的引用或其他东西