【问题标题】:How to dispose of dynamically loaded usercontrols/viewmodels when parent window is closed关闭父窗口时如何处理动态加载的用户控件/视图模型
【发布时间】:2012-10-29 20:06:29
【问题描述】:

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

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

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

【问题讨论】:

  • 您如何知道您的控件仍处于活动状态?

标签: wpf window dispose


【解决方案1】:

我认为您需要准确地思考什么负责创建您的视图和您的视图模型,以及什么负责确定某物是否可以关闭等等。

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 2015-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多