我在使用MVVMLight框架中的Messenger类在我的ViewModel之间传递参数时遇到问题。
这是我使用的代码:
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)中,我导航到SecondPage并在Messenger类中将人员作为参数发送。在这一点上,这个人构造得很好,并作为信息发送。
但是在SecondViewModel
构造函数中,该人为空:(
我有什么遗失的吗?
我认为我做错了什么......
供参考:
Windows Phone 8.1(Silverlight)
MVVMLight 5.0.2
Visual Studio 2013 Update 4
答案 0 :(得分:8)
我建议在SecondViewModel
注册后立即创建ViewModelLocator
。您可以使用Register
的重载方法来完成此操作。
SimpleIoc.Default.Register<SecondViewModel>(true);
这将确保在发送邮件之前确保Messenger
注册。
答案 1 :(得分:1)
发送邮件时,尚未创建SecondViewModel
;它仅在您访问SecondViewModel
的{{1}}属性时创建。因此,您的邮件已发送,并且未被任何操作处理。然后,当创建ViewModelLocator
实例时,消息已经发送...
我建议您在致电SecondViewModel
后发送消息,它应该解决问题。
答案 2 :(得分: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事件添加处理程序(带有一些额外的管道,请参阅博客),然后在ViewModel中实现INavigable接口。
然后,您就可以访问在Navigate调用中传递的参数:
NavigationServiceEx.Navigate(typeof(DestinationPage).FullName, yourParameter);
在ViewModel中实现的OnNavigatedToAsync方法:
public Task OnNavigatedToAsync(object parameter, NavigationMode mode)
{
if (parameter != null)
{
YourThing thing = parameter as YourThing;
this.UseYourThing(thing);
}
return Task.CompletedTask;
}