Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从itemscontrol中删除项时如何处置控件_C#_Wpf_Xaml - Fatal编程技术网

C# 从itemscontrol中删除项时如何处置控件

C# 从itemscontrol中删除项时如何处置控件,c#,wpf,xaml,C#,Wpf,Xaml,因此,我有一个包含信号图的分层数据模板的listview <HierarchicalDataTemplate DataType="{x:Type ViewModels:BusViewModel}" ItemsSource ="{Binding Path = bits}" > <Components:SignalGr

因此,我有一个包含信号图的分层数据模板的listview

 <HierarchicalDataTemplate 
                DataType="{x:Type ViewModels:BusViewModel}" 
                ItemsSource ="{Binding Path = bits}"                
                >
                <Components:SignalGraph 
                  x:Name="signal_graph"
                  />

如果我从itemslist中删除了一个项目,那么信号图仍然存在,并且仍然挂接到重画事件上,因此我为屏幕上没有的项目重画了事件

我的第一反应是去改变VirtualizationStackPanel.VirtualizationMode=“Standard” 以确保容器没有被重用,但这还不足以阻止重画

然而,我只是在这里使用虚拟化瓷砖面板:

我不认为它实现了回收。它看起来只是使用generator的remove和generatenext方法,而不是recycle方法。所以我很困惑为什么生成的对象没有被正确处理。当我查看面板的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);
        }
      }
    }
private void CleanUpItems(int minDesiredGenerated,int maxDesiredGenerated)
{
UIElementCollection children=this.InternalChildren;
IItemContainerGenerator generator=此.ItemContainerGenerator;
对于(int i=children.Count-1;i>=0;i--)
{
GeneratorPosition childGeneratorPos=新的GeneratorPosition(i,0);
int itemIndex=generator.IndexFromGeneratorPosition(childGeneratorPos);
if(itemIndexmaxDesiredGenerated)
{
发电机。拆除(childGeneratorPos,1);
RemoveInternalChildRange(i,1);
}
}
}
我发现小组的内部子级确实减少到了1,所以我认为WPF应该为我处理大部分的事情。因此,我认为我可能需要实现IDisposable或类似的东西,以确保销毁控件并分离所有事件处理程序


当从属于listview的itemssource的可观察集合中删除项目时,如何正确地处理这些项目?

您的做法是正确的。调用generator.Remove会从generators缓存中删除容器,但如果在项和容器之间还有事件或处理程序,则GC将不会收集容器

因此,释放所有处理程序,wpf将负责从内存中删除容器,实际上GC将删除它。正如你在第一句中提到的,你似乎有一些绘画活动。如果不释放该事件,则容器将无法最终确定


因此,只需释放其中的所有自定义逻辑,就可以了。

我刚刚连接到已卸载的事件并取消连接事件处理程序,现在代码工作正常。我猜在幕后,itemscontrol会在没有引用对象或其他东西的情况下尝试销毁该对象,谢谢,但我想我仍然很好奇WPF实际上是如何删除该事件的。WPF是否强制垃圾收集器尝试在该控件上运行,如果不存在对该控件的引用,则会将其删除?我猜它就是这样做的,因为如果WPF只是运行一个通用的垃圾收集器检查,那么WPF不会删除该事件,这将是低效的。你必须退订。wpf不做任何事情,只要GC觉得需要收集它,它就让GC收集它(意味着不存在其他引用)。