6

我在使用 MVVMLight 框架中的 Messenger 类在我的 ViewModel 之间传递参数时遇到问题。

这是我正在使用的代码:

视图模型定位器

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

主视图模型

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

第二视图模型

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

  • 视觉工作室 2013 更新 4

4

3 回答 3

9

我建议SecondViewModel一旦在ViewModelLocator. 您可以通过使用Register.

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

这将确保确保Messenger在发送消息之前进行注册。

于 2014-12-08T05:41:11.337 回答
1

当您发送消息时,SecondViewModel尚未创建;它仅在您访问SecondViewModel. ViewModelLocator因此,您的消息已发送,并且没有任何处理。然后,当SecondViewModel创建实例时,消息已经发送......

我建议您在致电后发送消息至NavigateTo,它应该可以解决问题。

于 2014-12-07T20:12:46.887 回答
0

您可以在 NavigationServicesEx.Navigate 方法调用中传递参数,而不是发送消息。

Marco Minerva 的这篇博客建议如何挂钩 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 接口。

然后,您将能够访问您在 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;
}
于 2017-12-09T17:38:48.347 回答