Reputation: 6017
I have a ListBox that is bound to a ListCollectionView, at one point I select an item in the listbox, then in the future I am recreating the ListCollectionView, but the ListBox is internally keeping a reference to an item from the old list. This is a problem because that item has a reference back to its parent container, and it is effectively causing a memory leak.
Here is a screenshot from .NET memory profiler showing how the ListBox's SelectedItem and SelectedValue are keeping a reference to the DataPoint object.
The new DataPoint object in the new ListCollectionView is equal to the existing selected one(because it has its own identifier field and I override object.Equals) but is not the same reference, how can I force the ListBox to change its SelectedItems so that it doesn't cause a memory leak? Is there a better way than having to forcefully unselect and reselect the items from the code behind?
Currently the WPF looks like:
<!-- Listbox of items -->
<ListBox
x:Name="ListBoxOfStuff"
ItemsSource="{Binding ListView}"
ItemTemplate="{Binding ItemTemplate}"
And in the code behind I have
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");
}
}
Upvotes: 2
Views: 547
Reputation: 503
Did the comments (above) resolve your question? Will's suggestion sounds like what you need. That's what I always do - have a separate property on your view-model that is bound to SelectedItem, or if you're using it as a multiple-selection listbox: SelectedItems (which is a collection). When a new collection is assigned to your bound property, the previous should be released. If it is not (and I have had that happen, in certain cases) making it re-bind by invalidating the binding, always cleared that up for me. You could also check to ensure that something else is not keeping a reference to that item. For example, I saw an implementation that raised an event, that contained a reference to a list-item's SelectedItem. It was not a weak-reference, and it lingered, causing a memory-leak. The cure, was to provide an id within that event that served to identify which item the user had just selected, but not an actual reference. You're doing the right thing, in using your profiler to check the memory situation (kudos).
Upvotes: 1