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