MGGggg

I have a class in my code that exposes an ObservableCollection. In a Window I have a ComboBox I want to bind to this ObservableCollection. To do this I use a CollectionViewSource that utilizes the Filter event to perform filtering logic, and set teh ComboBox's ItemSource to the CollectionViewSource's view. This works fine for the most part, except when I close the window. When I close the window, the window does not get released from memory. When ever the observable collection is modified, the Filter event gets fired.

The CollectionViewSource is scoped at the Window level, so I would have expected that when the Window is closed, the CollectionViewSource would be released. However, it seems as though the inner list, in this case the ObservableCollection must actually be what is calling the Filter event and not the CollectionViewSource. Am I missing something here Below is some pseudo code to show what I am doing.

public class SomeRandomClass

{

public static ObservableCollection<AnotherClass> MyList;

}

In a window I have the following code.....

public void InitMyComboBoxes

{

CollectionViewSource viewsource = new CollectionViewSource

viewSource.Source = SomeRandomClass.MyList;

viewSource.Filter += new FilterEventHandler(CB_Filter);

myComboBox.Items = viewsource.View;

}

private void CB_Filter(object sender, FilterEventArgs e)

{

///// Filtering logic.

}



Re: Windows Presentation Foundation (WPF) ObservableCollection, CollectionViewSource, and Filter Event odd behavior

Adam Smith - MSFT

<begin speculation>

Is this plausible

MyList.CollectionChanged event holds on to a delegate to a method in viewSource.

viewSource.Filter holds on to to the FilterEventHandler.

FilterEventHandler holds on to CB_Filter.

Also, viewsource.View's change event holds on to myComboBox (to notify on changes), and myComboBox of course holds on to its parent and children, so... everything lives forever!

<end speculation>

If this is what's happening, you may wish to hang on to your viewSource and clear the .Source property when the Window goes away to break this dependency.






Re: Windows Presentation Foundation (WPF) ObservableCollection, CollectionViewSource, and Filter Event odd behavior

Sam Bent - MSFT

Adam is pretty close. The real truth is:

MyList.CollectionChanged holds a delegate to a method in the view (a ListCollectionView).

view.Filter holds a delegate to a method in viewSource.

viewSource.Filter holds a delegate to a method in the window (the CB_Filter method).

Adam is wrong about change events holding on to myComboBox, but the damage is already done. The window holds on to its children, including the ComboBox, and everything lives forever.

This is a leak; I will open a bug about this. Adding a handler to a CollectionViewSource's Filter event should not extend the lifetime of the CollectionViewSource. The second reference ("view.Filter holds a delegate to a method in the CVS") extends the lifetime at least as long as the view - this is the bug.

However, it's worth noting that this bug is the only thing that makes your app work in the first place. Your app creates the CVS and assigns the reference to a local variable of the InitializeMyComboBox method, so when this method returns there should be no more references to the CVS and it should become eligible for garbage collection. The only reason it doesn't is the very reference that causes the leak. You could add an instance variable to your window class to hold a reference to the CVS, to keep the CVS alive as long as the window itself is alive.

Adam's proposed workaround won't work. Clearing viewSource.Source doesn't actually unhook the filter (it probably should). But removing your handler should work:

viewSource.Filter -= new FilterEventHandler(CB_Filter);






Re: Windows Presentation Foundation (WPF) ObservableCollection, CollectionViewSource, and Filter Event odd behavior

MGGggg

Thanks for the response. I actually had the CVS as the Window level (I guess I was a little lazy writing the pseudo-code) and I have be removing the event handler on Closing of the Window which does seem to work.