2010-09-13 288 views
3

我正在使用MVVM Light,并使用消息在ViewModels之间进行通信,以让ViewModel知道什么时候可以执行某些操作。我的问题是我注册了一条消息,然后多次收到它。所以为了防止我的程序执行一些操作,我不得不创建布尔标志来查看它是否已经被接收。任何想法为什么这样做,我怎么能阻止它?MVVM Light Messenger执行多次

+0

您的消息在哪里发送?您是否已经通过MVVM Light来源了解了邮件被多次发送的原因?在你的问题得到解答之前,你可以做一定量的工作,或者提供更多的细节。 – 2010-09-14 16:50:15

回答

1

我以前看过这个问题。它必须与被称为不止一次的Messenger.Default.Register相关。 MVVMLight Messenger类将注册相同的项目'x'次数。这就是为什么当你打电话给发送你多次。

任何人都知道如何防止MVVMLight注册多次?

+0

我发现我的问题,至少是因为其他视图模型和视图在记忆中。我仍然有一个问题,我需要从虚拟机发送消息到一个视图。我现在的问题是,此视图的所有以前的实例仍然在内存中,因此消息被发送和接收多次 – Jason 2010-12-14 14:27:07

8

确保在您不再需要它们时取消注册您的消息处理程序。信使保留对已注册方法的引用,这可以防止垃圾收集。

因此,对于ViewModels:确保在完成之后调用Cleanup(或者实现IDisposable并从那里调用Cleanup)。

对于视图(控件,Windows或类似),在视图的拆解发生的事件中调用Messenger.Unregister,例如, Unloaded事件。

这是MVVM的已知行为,并已在几个地方进行了讨论。

+1

...除了在WPF中,UserControl.Unloaded事件不保证被触发,按照http:/ /connect.microsoft.com/VisualStudio/feedback/details/575287/the-usercontrol-unloaded-event-is-not-raised-when-the-mainwindow-gets-closed - 因此并不那么容易。 – 2014-01-23 15:27:32

+0

我正在做的一点是你必须清理Messenger,否则,它将继续处理消息,尽管它不应该这样做。 Unloaded事件是一个地方,但它可能不是唯一的或最好的。 – AxelEckenberger 2014-01-23 16:01:22

5

很老的问题,但我做这个解决了这个问题:

static bool isRegistered = false;

,然后,在构造函数中:

if(!isRegistered) 
{ 
    Messenger.Default.Register<MyMessage>(this, OnMessageReceived); 
    isRegisterd = true; 
} 
+0

这是问题的可能修复方法,不要在构造函数中注册Messenger。 – 2013-05-07 14:02:04

1

真的老了,但想到我会在万一有人只是回答需要它。那时我对silverlight还是比较陌生的,这个问题最终成为内存泄漏,因为具有多个实例的viewModel仍然在内存中。

0

正如其他贡献者所说,同一条消息正在多次注册。我注意到这个行为发生在导航到View X的时候,然后导航回到View Z,其中消息在Z ViewModel的构造函数中被注册。一种解决方案是将NavigationCacheMode属性设置为必需

<Page 
    ........ 
    ........ 
    NavigationCacheMode="Required">