Passing a parameter between ViewModels using MVVMLight

I had a problem passing parameters between my ViewModels modules using the Messenger class in the MVVMLight Framework.

This is the code I'm using:

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; }); } 

In my MainViewModel (ShowPersonDetailsCommand), I go to the second page and send the person as a parameter in the Messenger class. At this point, the person is well designed and sent as a message.

But in the constructor of SecondViewModel person is null: (

Is there something I am missing?

I think I did something wrong ...

For information:

  • Windows Phone 8.1 (Silverlight)

  • MVVMLight 5.0.2

  • Visual Studio 2013 Update 4

+5
source share
3 answers

I suggest creating a SecondViewModel as soon as it is registered with the ViewModelLocator . You can do this using the overloaded Register method.

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

This will ensure that Messenger is registered before sending the message.

+8
source

When you sent the message, SecondViewModel has not yet been created; it is created only when accessing the SecondViewModel ViewModelLocator property. So your message has been sent, and nothing has been processed. Then, when the SecondViewModel instance was created, the message is already sent ...

I suggest you send a message after calling NavigateTo , it should fix the problem.

+1
source

Instead of sending a message, you can pass a parameter in a call to the NavigationServicesEx.Navigate method.

This blog post by Marco Minerva advises connecting to the Frame_Navigating event (which is missing from the ServiceEx vanilla navigation class) to access the argument the destination page is being moved to.

Create the INavigable interface described in the blog:

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

Add a handler for the Frame.Navigating event in the NavigationServicesEx class (with additional fixtures, see the blog), then implement the INavigable interface in your ViewModels.

Then you can access the parameter that you passed in your navigation call:

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

In the OnNavigatedToAsync method that you implement in your ViewModel:

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

Source: https://habr.com/ru/post/1208540/


All Articles