1

我们有一个启动子窗口的主窗口。该子窗口动态加载自定义用户控件。在这些用户控件的构造器中,我传递了一个主对象,从这个主对象中,生成一个特定于用户控件的视图模型并将其分配为它的数据上下文。

所有这些都运行良好。但是,我发现当我关闭子窗口时,至少我的一些自定义用户控件仍然处于活动状态。我应该如何清理我的控件/视图模型?在主窗口关闭之前,似乎什么都没有被调用。没有析构函数,没有 Dispatcher.ShutdownStarted,没有可用的 dispose,没有关闭事件,我什么也找不到。

有人知道窗户关闭后应该怎么做才能正确清理吗?

4

1 回答 1

1

我相信你需要仔细考虑是什么负责创建你的视图和你的视图模型,以及什么负责确定某些东西是否可以关闭等等。

对于任何创造了破坏它的东西来说,这通常是一个好主意。因此,如果您的子窗口正在创建自定义用户控件,它可能应该负责删除它们。但是,我相信如果您的所有对象都没有引用(或强事件订阅),它最终应该被垃圾收集。您可以实现终结器/析构函数并将 Debug.String 输出到输出窗口以查看最终可能发生的时间。一个好的内存分析器也可能是一个好主意。但是,您也可能需要更精确地控制 ViewModel 何时关闭。

很难确切地说出在您的场景中应该发生什么,因为它实际上取决于您的确切和具体设置。让我向您描述我在应用程序中遇到的一个场景。我有几个视图显示在标签页中。标签页有一个 X 按钮来关闭标签,我的视图包含一个托管的 Windows 窗体控件,需要调用 .Dispose() 来清理资源,并且需要通知它何时取消订阅文件菜单系统。所以,最初,我遇到了一个问题......当标签页删除视图时,我的 ViewModel 如何取消订阅命令?WPF 控件中包含的视图如何知道它何时被删除?这就是我想出的

  1. 标签页本身不应该告诉我的程序是否可以关闭视图
  2. 我需要能够在程序逻辑的情况下取消关闭事件(文件已保存?是/否/取消)
  3. 我需要能够检测它何时关闭,以便我可以在那一刻清理/取消注册

我的解决方案是在我的视图模型中实现一个名为 IRemovable 的接口,它公开了一个 Removable 布尔值和一个返回布尔值(是否被删除)的 Remove() 方法。如果 Removable 为真,我的选项卡控件仅显示 X 按钮,选项卡控件的 Closing 触发了 IRemovable ViewModel 的 Remove(),如果它返回 false,则在 ViewModel 的 Remove 返回 false 时将事件 args Canceled 属性设置为 true。

因此,删除视图模型可能会提示用户确认、取消注册命令等。视图可以处理 Closed 事件并在任何 Windows 窗体组件上调用 Dispose 等。(当然,我必须检查我的 View.DataContext 是否为可移动)。

无论如何,我知道这不是一个确切的答案,但希望它可以帮助你想出一些关于如何解决你自己的问题的想法

于 2012-10-29T20:52:53.833 回答