2011-12-15 75 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執行類似的功能,你可以將它們結合在一起,但我沒有嘗試過。