2010-05-21 79 views
1

我有一個WPF窗口打開一個模式子窗口來加載一些數據。這兩個窗口都有自己的viewmodel,現在我有這個問題:關閉子窗口後,它似乎仍然在後臺運行!WPF親子窗口:綁定參考問題

要關閉子窗口,我從viewmodel命令設置DialogResult;現在,如果我創建了一個新數據,然後從父窗口編輯它(以前關閉了子窗口),那麼子窗口仍會捕獲先前綁定的屬性的屬性更改事件。

如何避免這種情況?

當我關閉模態窗口時,我會清除每個數據的引用。這是最好的做法嗎?

回答

3

確保您不保留對您的窗口的任何引用,即使是間接引用。最常見的泄漏原因之一是事件。如果窗口B將事件處理程序添加到窗口A的事件中,則B將不會被釋放,直到A也爲止。

例如,如果您直接收聽財產變更,則應使用Weak Event Pattern,並用PropertyChangedEventManager .AddListener的呼叫替換您的所有+ =。一般來說,您添加到事件中的每個強處理程序都應該被移除以避免泄漏。

有關.NET中的泄漏的更多信息,請參閱this MSDN article

您可以像Scitech的mem profiler或Jetbrains dotTrace一樣使用內存分析器來查看哪些操作將窗口保留在內存中。


編輯:在回答您的意見,你的情況比我首先想到真的簡單了:垃圾收集器根本沒有收集窗口呢。爲了測試目的,在Test_Click上添加GC.Collect可解決此問題。

在窗體關閉時,從ComboBox中刪除SelectionChanged事件,以便您可以讓GC完成其工作並在以後回收表單而不會出現問題。如果您確實需要整個表單才能立即發佈,則可以考慮撥打GC.Collect,儘管您應該儘可能避免。

編輯2:在回答你的第三個評論,它應該只適用於視圖之間共享的對象,並在視圖中的變化將在一個共享對象改變的東西回來事項。在您的測試項目中,SelectionChanged在原始列表中不做任何事情,因此事件是否被提出並不重要。表格將最終收集。

+0

我在檢查...我的實體實現了INotifyPropertyChanged接口,該實體的一個屬性綁定了ComboBox的SelectedValue, ComboBox在後面的子窗口代碼中有一個用於SelectionChanged的事件處理程序。 然後,在關閉子窗口後,如果我在父窗口上更改相同的實體屬性,則子窗口中ComboBox的selectionchanged事件處理程序正在觸發。 – 2010-05-21 09:20:35

+0

我創建了一個顯示行爲的愚蠢項目。你可以從這裏下載它:http://www.olisoft-olisistemi.it/uploads/WpfApplication2.zip 1)點擊「ChildWindow」按鈕 2)關閉ChildWindow 3)點擊「測試」按鈕 - > ChildWindow中的ComboBox的SelectionChanged事件觸發! Waht錯了嗎?弱事件模式是解決方案? – 2010-05-21 12:53:44

+0

謝謝,但是如果我的窗口在後面的代碼上有更多事件,每次我都要刪除所有處理程序關閉事件?或者存在更好的方法? – 2010-05-21 15:03:53