更新DataSource时,ListBox不刷新SelectedItem,而新源具有等于'等于'的SelectedItem

时间:2014-03-11 16:58:07

标签: c# wpf mvvm listbox

我有一个ListBox绑定到ListCollectionView,我在一个点上选择了一个列表框中的项目,然后将来我重新创建ListCollectionView,但ListBox在内部保留对旧列表中项目的引用。这是一个问题,因为该项具有返回其父容器的引用,并且它实际上导致内存泄漏。

以下是.NET内存分析器的屏幕截图,显示了ListBox的SelectedItem和SelectedValue如何保持对DataPoint对象的引用。

enter image description here

新的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");
    }
}

1 个答案:

答案 0 :(得分:1)

上述评论(上述)是否解决了您的问题?威尔的建议听起来像你需要的。这就是我经常做的事情 - 在您的视图模型上有一个绑定到SelectedItem的单独属性,或者如果您将其用作多选列表框:SelectedItems(这是一个集合)。将新集合分配给绑定属性时,应释放前一个集合。如果不是(并且我已经在某些情况下发生了这种情况)通过使绑定无效而重新绑定,那么总是为我清除它。您还可以检查以确保其他内容未保留对该项目的引用。例如,我看到了一个引发事件的实现,它包含对list-item的SelectedItem的引用。它不是一个弱引用,它徘徊,导致内存泄漏。解决方法是在该事件中提供id,用于识别用户刚刚选择的项目,但不是实际参考。你在使用你的探查器检查内存情况(荣誉)时做了正确的事。