从itemscontrol中删除项目时如何处理控件

时间:2013-12-02 21:00:52

标签: c# wpf xaml

所以我有一个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的可观察集合中删除项目时如何正确处理项目?

2 个答案:

答案 0 :(得分:1)

你走在正确的轨道上。调用generator.Remove会从生成器缓存中删除容器,但如果项目和容器之间仍有事件或处理程序,则GC不会收集容器。

因此释放所有处理程序,wpf将负责从内存中删除容器,实际上GC会将其删除。就像你在第一句中提到的那样,你似乎有一些绘画事件。如果您不释放该事件,则容器将无法完成。

所以简单地释放你在那里的所有自定义逻辑,你应该做得很好。

答案 1 :(得分:0)

我只是挂钩了卸载的事件并解除了事件处理程序,现在代码工作正常。我在幕后猜测itemscontrol试图破坏对象,如果没有对它的引用或其他东西