MVVM光:如何注销使者 [英] MVVM Light: how to unregister Messenger

查看:218
本文介绍了MVVM光:如何注销使者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我爱MVVM光的使者和灵活性,但我遇到了内存泄漏,当我忘记明确注销接收者(在Silverlight 4)。

I love the MVVM Light's Messenger and its flexibility, however I'm experiencing memory leaks when I forget to explicitly unregister the recipients (in Silverlight 4).

原因是这里解释,但我与它的罚款,因为我相信这是一个很好的做法,明确注销收件人反正而不是依靠信使的使用弱引用。但问题是谈何容易

The cause is explained here, but I'm fine with it as I believe it's a good practice to explicitly unregister the recipients anyways rather than relying on the Messenger's use of weak references. The problem is that is easier said than done.


  • 的ViewModels 很简单:你平时有充分掌控自己的生命周期,可以只清理()他们时,他们不需要了。

  • ViewModels are easy: you usually have full control over their lifecycle and can just Cleanup() them when they are not needed anymore.

<因为他们被实例化,并通过破坏的DataTemplates STRONG>查看,另一方面是棘手。外汇。你能想到一个的ItemsControl MyView的作为DataTemplate中,绑定到的ObservableCollection<的; MyViewModel> 。在 MyView的控件创建/绑定引擎收集的,你有没有什么好办法对他们手动调用清理()。

Views on the other hand are trickier because they are instantiated and destroyed via DataTemplates. For ex. you can think of an ItemsControl with MyView as DataTemplate, bound to an ObservableCollection<MyViewModel>. The MyView controls are created/collected by the binding engine and you have no good way to manually call Cleanup() on them.

我心里有一个解决方案,但想知道这是否是一个体面的图案或有更好的选择。
的想法是从视图模型发送特定信息告诉相关的视图(S)处理:

I have a solution in mind but would like to know if it's a decent pattern or there are better alternatives. The idea is to send a specific message from the ViewModel to tell the associated View(s) to dispose:

public class MyViewModel : ViewModelBase
{
    ...

    public override void Cleanup()
    {
        // unregisters its own messages, so that we risk no leak
        Messenger.Default.Unregister<...>(this);

        // sends a message telling that this ViewModel is being cleaned
        Messenger.Default.Send(new ViewModelDisposingMessage(this));

        base.Cleanup();
    }
}

public class MyView : UserControl, ICleanup
{
    public MyView()
    {
         // registers to messages it actually needs
         Messenger.Default.Register<...>(this, DoSomething);

         // registers to the ViewModelDisposing message
         Messenger.Default.Register<ViewModelDisposingMessage>(this, m =>
             {
                 if (m.SenderViewModel == this.DataContext)
                     this.Cleanup();
             });
    }

    public void Cleanup()
    {
        Messenger.Default.Unregister<...>(this);
        Messenger.Default.Unregister<ViewModelDisposingMessage>(this);
    }
}



所以,当你在一个视图模型调用清理()所有使用它作为DataContext的意见将exeute当地清理()也是如此。

So when you call Cleanup() on a viewModel all the views that use it as DataContext will exeute their local Cleanup() as well.

你怎么认为呢?我失去了一些东西明显?

What do you think? Am I missing something obvious?

推荐答案

该ViewModelLocator类有助于保持集中存储您的ViewModels。你可以使用这个类来帮助管理新版本和清理旧的。我总是认为我引用视图模型通过定位器,所以我总是有一些代码,我可以运行,以管理这些事情。你可以试试。

The ViewModelLocator class helps keep a centralized store for your viewmodels. You can use this class to help manage new versions and clean up old ones. I always reference my viewmodel from view via the locator, so I always have code I can run to manage these things. You could try that.

同时,我用的清理方法来调用 Messenger.Unregister(本),其中清理从信使该对象的所有引用。你必须调用.Cleanup()每一次,但生活就是这样:)

As well, I use the Cleanup method to call Messenger.Unregister(this), which cleans up all references from the messenger for that object. You have to call .Cleanup() every time, but such is life :)

这篇关于MVVM光:如何注销使者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆