在View中将对象从VM传递到VM

时间:2011-12-15 20:24:00

标签: windows-phone-7 mvvm-light messages

我花了很多时间探索在VM之间共享对象的选项,我找到了一个成功的解决方案,但这并不是最优雅的:

假设我想从VM1发送V1中显示的类TestClass的_testObject对象,DataContext显然是VM1到VM2,并在视图V2中显示它。

public class VM1: ViewModelBase
{
   ...

   public VM1 ()
   {
      ...

      Messenger.Default.Register <bool> (this, "isLoaded" t => Messenger.Default.Send<TestClass> (_testObject "myObject"));
    }

    ...
}

    public partial class V2: PhoneApplicationPage
    {
       public V2 ()
       {
          InitializeComponent ();
       }

       protected override void OnNavigatedTo (System.Windows.Navigation.NavigationEventArgs e)
       {
          Messenger.Default.Register <TestClass> (this.DataContext "myObject", mo => (this.DataContext and VM2). PropertyInVM2 = mo);
          Messenger.Default.Send <bool> (true, "isLoaded");
          base.OnNavigatedTo (e);
       }

       protected override void OnNavigatedFrom (System.Windows.Navigation.NavigationEventArgs e)
       {
          Messenger.Default.Unregister <TestClass> (this.DataContext "myObject");
          base.OnNavigatedFrom (e);
       }
    }

因此,如果app被导航到V2,它会等到页面被创建,然后发送在VM1中捕获的消息“isLoaded”,然后VM1向VM2发送包含所需对象的消息。

不,我不喜欢这种方式,我不想要代码中的bihnd。谁能告诉我更优雅的方式?

2 个答案:

答案 0 :(得分:1)

[警告:既然你用MVVM-Light标记了这个问题,并在帖子中提到了Messenger,我认为你正在使用MVVM Light框架。]

我过去所做的是让VML在应用程序启动时显式创建两个VM,或者为事件安装VML并根据需要将它们从VM传递给VM。

  • 在第一种情况下,VM2将注册以收听消息,VM1将发送消息。由于VML实例化了两个VM,因此当发送消息并且一切都按预期工作时,两者都是活动的。
  • 在第二种情况下,VML始终处于活动状态,并且可以在VM1发送消息时根据需要延迟加载VM2。

在这两种情况下,V1和V2都没有参与消息传递,这很好。

第三种选择,取决于您的应用程序复杂性/需求/架构/等,是在V1和V2之间共享VM1。然后你不必在任何地方传递任何数据:)这种方法适用于小型应用程序,但如果你的应用程序很复杂,你很容易遇到麻烦。

这两种方法都有它的优点和缺点,但这就是我理解你可以用MVVM Light做到这一点的方法。 FWIW - EventAggregator是Prism的一部分,不是MVVM Light的一部分,因此使用EventAggregator意味着从Prism框架中获取您可能想要或不想做的其他依赖。由于EventAggregator和Messenger执行类似的功能,您可以将它们组合在一起,但我没有尝试过。

答案 1 :(得分:0)

我建议使用EventAggregator并通过您的界面订阅/发布从VM到另一个VM的消息。

使用IoC更加优雅,让它可以处理VMS的通信。