【问题标题】:When to dispose ViewModel in MVVM Light何时在 MVVM Light 中处理 ViewModel
【发布时间】:2011-08-12 07:26:09
【问题描述】:

我正在考虑开始使用 MVVM Light,并且遇到了“新”ICleanup 界面。我只是想知道您何时会清理 VM...当您离开该页面时?

另外,我看到 ViewModelLocator 中有一个 Main Cleanup,它应该清理所有 VM...什么时候使用它?

非常感谢

问候, 毛罗

【问题讨论】:

    标签: mvvm-light


    【解决方案1】:

    ICleanup 接口相对于IDispose 实现(以前存在)的优势在于 - 正如 Laurent 所说 - 您可以更频繁地调用它,而无需将 VM 标记为已处置。这意味着,当您想要/需要取消注册 VM 的消息处理时,您应该调用 ICleanup.Cleanup。显然,在这种情况下,您需要有一个方法来在以后需要时再次注册所有消息处理程序。

    就个人而言,我更喜欢IDispose 处理VM 清理的方式,尤其是当我倾向于IOC 容器时。但是,我可以看到 Laurent 的案例,并且在 VM 上实现 IDisposable 调用 Cleanup 并非易事。

    通常,处置/清理 VM 的时间点取决于它的实例化方式和对象的生命周期。这些决定取决于您的应用程序设计,并且没有明确的指导说明何时您应该这样做。但请记住,每当您在视图模型中注册消息处理程序时,它必须完成 - 在其他情况下,它并不是严格需要的。

    在谈论消息处理程序时,不要忘记在您的视图中取消注册它们,当您在那里注册消息处理程序时(请参阅this post)。 - 再想一想,我将代码放在这里以使其清楚并以供将来参考:

    在您的视图的构造函数中的代码隐藏文件中添加以下代码,以确保在卸载视图时释放注册的消息处理程序:

    public MyView() {
        this.Unloaded += (o, e) => { Messenger.Unregister(this); }
    }
    

    【讨论】:

    • 感谢您的回复。我现在更好地理解了在使者之后清理的整个概念
    • 我认为信使使用 Wea​​kReference 的事实是不需要取消注册,而且会因为清理以外的其他原因而取消注册。
    • @RalphShillington:它应该这样做,但它没有。这是一个已知问题。注册处理程序时,它是导致引用被持有的函数,尽管它不应该被持有。这样做的原因是,对于匿名和静态函数,对函数的弱引用不起作用。 Laurent、其他一些人和我对此进行了调查,最好的建议是……注销!
    • 只是发现在这种情况下使用 Unloaded 的问题。在我看来,如果我的视图托管在 TabItem 中并且用户切换到另一个 TabItem,则会引发 TabItem 的 Unloaded。
    • 是的,这可能是个问题。但是,这也取决于您的应用程序的设计。通常,一旦不再需要视图实例,我就不会保留它。如果您需要抓住窗口,您可以考虑另一种初始化策略,例如在显示窗口之前调用方法帽子。
    猜你喜欢
    • 2013-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-25
    相关资源
    最近更新 更多