我有一个ListBox绑定到ListCollectionView,我在一个点上选择了一个列表框中的项目,然后将来我重新创建ListCollectionView,但ListBox在内部保留对旧列表中项目的引用。这是一个问题,因为该项具有返回其父容器的引用,并且它实际上导致内存泄漏。
以下是.NET内存分析器的屏幕截图,显示了ListBox的SelectedItem和SelectedValue如何保持对DataPoint对象的引用。
新的ListCollectionView中的新DataPoint对象等于现有的选定对象(因为它有自己的标识符字段并且我覆盖了object.Equals)但是不是相同的引用,我如何强制ListBox更改其SelectedItems这样它就不会导致内存泄漏?有没有比强制取消选择并重新选择后面代码中的项目更好的方法?
目前WPF看起来像是:
<!-- Listbox of items -->
<ListBox
x:Name="ListBoxOfStuff"
ItemsSource="{Binding ListView}"
ItemTemplate="{Binding ItemTemplate}"
在我背后的代码中
public ListCollectionView ListView
{
get { return _listview; }
private set
{
if (_listview == value)
return;
_totalItemsInCollection = value.Count;
_listview = value;
_listview.Filter = this.ApplyFilter;
RaisePropertyChanged("ListView");
RaisePropertyChanged("FilteredInCount");
}
}
答案 0 :(得分:1)
上述评论(上述)是否解决了您的问题?威尔的建议听起来像你需要的。这就是我经常做的事情 - 在您的视图模型上有一个绑定到SelectedItem的单独属性,或者如果您将其用作多选列表框:SelectedItems(这是一个集合)。将新集合分配给绑定属性时,应释放前一个集合。如果不是(并且我已经在某些情况下发生了这种情况)通过使绑定无效而重新绑定,那么总是为我清除它。您还可以检查以确保其他内容未保留对该项目的引用。例如,我看到了一个引发事件的实现,它包含对list-item的SelectedItem的引用。它不是一个弱引用,它徘徊,导致内存泄漏。解决方法是在该事件中提供id,用于识别用户刚刚选择的项目,但不是实际参考。你在使用你的探查器检查内存情况(荣誉)时做了正确的事。