5

我在使用MVVMLight框架中的Messenger類在我的ViewModels之間傳遞參數時遇到問題。使用MVVMLight在ViewModels之間傳遞參數

這是我使用的代碼:

ViewModelLocator

public ViewModelLocator() 
{ 
    ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); 

    SimpleIoc.Default.Register<INavigationService, NavigationService>(); 

    SimpleIoc.Default.Register(() => new MainViewModel(NavigationService)); 
    SimpleIoc.Default.Register(() => new SecondViewModel(NavigationService)); 
} 

public MainViewModel MainViewModel 
{ 
    get { return SimpleIoc.Default.GetInstance<MainViewModel>(); } 
} 

public SecondViewModel SecondViewModel 
{ 
    get { return SimpleIoc.Default.GetInstance<SecondViewModel>(); } 
} 

public INavigationService NavigationService 
{ 
    get { return SimpleIoc.Default.GetInstance<INavigationService>(); } 
} 

MainViewModel

private void ShowPersonDetailsCommand(object obj) 
{ 
    Messenger.Default.Send((Person)obj); 
    _navigationService.NavigateTo(new Uri("/SecondPage.xaml", UriKind.Relative)) 
} 

SecondViewModel

public SecondViewModel(INavigationService navigationService) 
{ 
    _navigationService = navigationService; 

    Messenger.Default.Register<Person>(
     this, 
     person => 
     { 
      Person = person; 
     }); 
} 

在我的MainViewModel(ShowPersonDetailsCommand)中,我正在導航到第二頁並在Messenger類中發送一個人作爲參數。此時,該人構建良好並作爲消息發送。

但在SecondViewModel構造函數,這個人是無效:(

有什麼我失蹤

我認爲我做錯了什麼......

爲了您的信息?

  • 的Windows Phone 8.1(Silverlight的)

  • MVVMLight 5.0.2

  • 的Visual Studio 2013更新4

回答

8

我建議立即創建SecondViewModel只要它在ViewModelLocator註冊。您可以通過使用Register的重載方法來完成此操作。

SimpleIoc.Default.Register<SecondViewModel>(true); 

這將確保確保Messenger註冊發生在發送消息之前。

+0

這一個爲我工作,謝謝:) – 2014-12-09 16:56:35

1

當你發送的消息,該SecondViewModel尚未建立;它僅在您訪問ViewModelLocatorSecondViewModel財產時才創建。所以你的信息被髮送了,並沒有被任何東西處理。然後,當創建SecondViewModel實例時,該消息已經被髮​​送...

我建議你在呼叫NavigateTo之後發送消息,它應該解決問題。

+0

我做到了,但它不會改變任何東西:( – 2014-12-07 20:22:26

+0

@Christophe,您的NavigationService如何實現?NavigateTo方法是否可以傳遞參數以傳遞到目標頁面?如果可以,它可能是在ViewModels之間傳遞數據的更好方法... – 2014-12-07 22:47:42

+0

我的NavigationService ca n以狀態(對象)作爲參數。但問題是我不想在後面的代碼中獲得這個參數。因爲AFAIK我們只有在重寫OnNavigatedTo時才能獲得該狀態! – 2014-12-08 00:33:51

0

您可以在NavigationServicesEx.Navigate方法調用中傳遞參數,而不是發送消息。

Marco Minerva的blog建議如何在目標頁面導航到時訪問參數,以便連接到Frame_Navigating事件(它從vanilla NavigationServiceEx類中丟失)。

創建的博客中描述的INavigable接口:

public interface INavigable 
{ 
    Task OnNavigatedToAsync(object parameter, NavigationMode mode); 
    void OnNavigatingFrom(NavigatingCancelEventArgs e); 
    void OnNavigatedFrom(); 
} 

添加處理在NavigationServicesEx類Frame.Navigating事件(有一些額外的管道,看博客)則實現您的ViewModels的INavigable接口。

然後,您將能夠訪問您在導航調用中傳遞的參數:

NavigationServiceEx.Navigate(typeof(DestinationPage).FullName, yourParameter); 

在OnNavigatedToAsync方法,你在你的視圖模型實現:

public Task OnNavigatedToAsync(object parameter, NavigationMode mode) 
{ 
    if (parameter != null) 
    { 
     YourThing thing = parameter as YourThing; 
     this.UseYourThing(thing); 
    } 
    return Task.CompletedTask; 
}