C# 从itemscontrol中删除项时如何处置控件
因此,我有一个包含信号图的分层数据模板的listviewC# 从itemscontrol中删除项时如何处置控件,c#,wpf,xaml,C#,Wpf,Xaml,因此,我有一个包含信号图的分层数据模板的listview <HierarchicalDataTemplate DataType="{x:Type ViewModels:BusViewModel}" ItemsSource ="{Binding Path = bits}" > <Components:SignalGr
<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收集它(意味着不存在其他引用)。