views:

466

answers:

1

I have a WPF Window that open a modal child window to load some data. Both window have a own viewmodel, now I have this problem: after I close the child window it seems still running in background!

To close the child window I set DialogResult from viewmodel command; now, if I create a new data and then I edit it from parent window (with the child window closed before), the child window still capture the property changed event for the properties previously bind.

How can avoid this?

I would clear every reference with data when I close modal window. Which is the best practise to do it?

+2  A: 

Ensure that you don't keep any references to your window, even an indirect one. One of the most common cause of leaks are events. If a window B is adding an event handler to an event of window A, B won't be released until A is also.

For example, if you're directly listening to property changes, you should use the Weak Event Pattern and replace all your += with a call to PropertyChangedEventManager.AddListener. In general, every strong handler you add to an event should be removed to avoid leaking.

More information about leaks in .NET in this MSDN article.

You can use a memory profiler like Scitech's mem profiler or Jetbrains dotTrace to see what ojects are keeping your windows in memory.


Edit: In response to your comments, your case is really simpler than I first thought: the Garbage Collector simply didn't collect the window yet. Adding GC.Collect on Test_Click for testing purposes solves the issue.

Here, remove the SelectionChanged event from the ComboBox when the form is closing so you can let the GC do its job and reclaim the form later without having problems. If you really need the whole form to get released right now, you might consider calling GC.Collect although you should avoid it when you can.

Edit 2: In response to your third comment, it should only matters for objects that are shared between views, and where the changes in the view will change something back in a shared object. In your test project the SelectionChanged does nothing on the original list so it doesn't really matter if the event is raised or not. The form will get collected eventually.

Julien Lebosquain
I'm checking...my entity implements INotifyPropertyChanged interface, a property of the entity is bind with SelectedValue of ComboBox in child win; the ComboBox, on child window code behind, have an event handler for SelectionChanged.Then, after I closed the child window, if I change the same entity property on parent window the selectionchanged event handler of ComboBox in child window is firing.
LukePet
I have created a stupid project that show the behavior. You can download it from thi url: http://www.olisoft-olisistemi.it/uploads/WpfApplication2.zip1) Click on "ChildWindow" button2) Close the ChildWindow3) Click on "Test" button -> the SelectionChanged event of ComboBox in ChildWindow fire!Waht's wrong? Weak Event Pattern is the solution?
LukePet
Thanks, but if my Window have more events on code behind, everytime have I to remove all handler con closing event? Or exist a better approach?
LukePet