WPF父子窗口:绑定引用问题

发布于 2024-09-02 12:45:19 字数 241 浏览 2 评论 0原文

我有一个 WPF 窗口,它打开一个模式子窗口来加载一些数据。两个窗口都有自己的视图模型,现在我遇到这个问题:关闭子窗口后,它似乎仍在后台运行!

要关闭子窗口,我从 viewmodel 命令设置 DialogResult;现在,如果我创建一个新数据,然后从父窗口编辑它(之前关闭子窗口),子窗口仍然捕获先前绑定的属性的属性更改事件。

如何避免这种情况呢?

当我关闭模式窗口时,我会清除所有带有数据的引用。最好的做法是什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我不在是我 2024-09-09 12:45:19

确保不保留对窗口的任何引用,即使是间接引用。泄漏的最常见原因之一是事件。如果窗口 B 向窗口 A 的事件添加事件处理程序,则直到 A 也添加事件处理程序后,B 才会被释放。

例如,如果您直接侦听属性更改,则应使用 弱事件模式 并将所有 += 替换为对 PropertyChangedEventManager.AddListener。一般来说,添加到事件中的每个强处理程序都应该被删除以避免泄漏。

有关 .NET 中泄漏的更多信息,请参阅这篇 MSDN 文章

您可以使用内存分析器(例如 Scitech 的 mem 分析器或 Jetbrains dotTrace)来查看哪些对象将窗口保留在内存中。


编辑:针对您的评论,您的情况确实比我最初想象的要简单:垃圾收集器只是还没有收集窗口。在 Test_Click 上添加 GC.Collect 进行测试可以解决该问题。

在这里,当表单关闭时,从 ComboBox 中删除 SelectionChanged 事件,这样您就可以让 GC 完成其工作并稍后回收表单,而不会出现问题。如果您确实需要立即发布整个表单,您可以考虑调用 GC.Collect,尽管您应该尽可能避免它。

编辑2:针对您的第三条评论,它应该只对视图之间共享的对象有意义,并且视图中的更改将在共享对象中更改某些内容。在您的测试项目中,SelectionChanged 对原始列表不执行任何操作,因此事件是否引发并不重要。该表格最终将被收集。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文