我正在开发一个WPF应用程序,我正在使用一个ObservableCollection of CustomObject
public ObservableCollection<ProjectsToShow> Projects{get;set;}
ProjectsToShow类的定义
public class ProjectsToShow
{
public ProjectsToShow()
{
Wells = new ObservableCollection<WellsToShow>();
}
public Project ProjectObject { get; set; }
ObservableCollection<WellsToShow> _wells;
public ObservableCollection<WellsToShow> Wells{get;set;}
}
此类初始化WellsToShow的集合,其定义为
public class WellsToShow
{
public WellsToShow()
{
Datasets = new ObservableCollection<DatasetsToShow>();
}
public Well WellObject { get; set; }
ObservableCollection<DatasetsToShow> _datasets;
public ObservableCollection<DatasetsToShow> Datasets
{
get { return _datasets; }
set
{
_datasets = value;
NotifyPropertyChanged("Datasets");
}
}
}
还有一个这样的等级。
现在我正在使用内存分析器分析我的应用程序,并且它不断将集合中的对象添加到内存中。我期待着打电话
Projects.Clear();
将从内存中释放所有对象,但它不会那样工作。即使我尝试将项目设置为null,但即使这样也不起作用。 WellsToShow和DatasetToShow的对象仍然保留在内存中。因此,出于测试目的,我尝试使用此代码
foreach(var project in MainViewModel.Projects)
{
foreach(var well in project.Wells)
{
well.Datasets.Clear();
}
project.Wells.Clear();
}
MainViewModel.Projects.Clear();
根据内存分析器,它们不再存在于内存中。为了记录,每次运行探查器时,它首先运行GC.Collect,然后进行分析。
有些人可以解释这件事是如何运作的。如果这是清除集合的正确方法,那么我需要在所有项目中运行并修复此事。
更新1,将此集合绑定到视图
我将Project属性绑定到TreeView控件并调查它的分析器。这个控件保留了我的收藏,我相信清除项目源集合应该可以完成这项工作,但事实并非如此。
<TreeView VirtualizingStackPanel.IsVirtualizing="False" ItemsSource="{Binding Projects}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type bll:ProjectsToShow}" ItemsSource="{Binding Wells}">
<TextBlock HorizontalAlignment="Stretch" Text="{Binding ProjectName}" x:Name="TextBlockProject" Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}">
<TextBlock.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}" >
<MenuItem
Command="{Binding FileEditProjectCommand}">
<MenuItem.Header>
<TextBlock Text="{DynamicResource EditProject}"/>
</MenuItem.Header>
</MenuItem>
<MenuItem Command="{Binding FileDeleteProjectCommand}">
<MenuItem.Header>
<TextBlock Text="{DynamicResource DeleteProject}"/>
</MenuItem.Header>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type bll:WellsToShow}" ItemsSource="{Binding Datasets}">
<TextBlock HorizontalAlignment="Stretch" Text="{Binding WellName}" Tag="{Binding DataContext,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}">
<TextBlock.ContextMenu>
<ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
<MenuItem Command="{Binding FileEditWellCommand}">
<MenuItem.Header>
<TextBlock Text="{DynamicResource EditWell}"/>
</MenuItem.Header>
</MenuItem>
<MenuItem Command="{Binding FileDeleteWellCommand}">
<MenuItem.Header>
<TextBlock Text="{DynamicResource DeleteWell}"></TextBlock>
</MenuItem.Header>
</MenuItem>
</ContextMenu>
</TextBlock.ContextMenu>
</TextBlock>
</HierarchicalDataTemplate>
更新2个附加截图
答案 0 :(得分:1)
如果视觉对象对应于集合中的对象,则这些可视对象将保留在其各自的DataContexts中的那些引用。确保仅在对象直观清除后才运行内存配置文件。
我还建议Snoop用于任何WPF调试工作,因为这可能会显示您的对象以及引用它们的内容。