2011-12-15 97 views
0

我花了很多时间寻找解决方案共享虚拟机之间的物体,我来到了一个成功的解决方案中,但不完全是最优雅:传递一个对象到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); 
     } 
    } 

因此,如果应用程序导航到V2,它等到创建的页面,然后将其在VM1捕捉消息“isLoaded”,然后VM1发送一条消息,你需要VM2的对象。

不,我不喜欢这种方式,我不想在代码bihnd。任何人都可以建议我更优雅的方式?

回答

0

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

使用IoC更加优雅,让VMS的沟通由它处理。

1

[警告:既然你标记MVVM,光这个问题,在您的文章提到的使者,我假定你正在使用的MVVM光框架]

我已经在做过去是要么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执行类似的功能,你可以将它们结合在一起,但我没有尝试过。

相关问题